Inline Functions don't have Internal Linkage without -O option
Martin v. Loewis
Sat Oct 23 04:35:00 GMT 1999
> If I compile them with -O option, or replace the keyword "inline" in
> the source code with "static inline", I have the correct result.
Thanks for your bug report. I agree with most of your analysis, but I
fail to see the bug. 7.1.2/4 says
# If a function with external linkage is declared inline in one
# translation unit, it shall be declared inline in all translation
# units in which it appears; no diagnostic is required.
Since this function is not declared static, it has external linkage.
So the two declarations in foo.cc and bar.cc declare in fact the same
Further, 3.2/5 says
# There can be more than one definition of a class type (clause 9),
# enumeration type (7.2), inline function with external linkage
# (7.1.2), class template (clause 14), nonÃÂstatic function template
# (14.5.5), static data member of a class template (188.8.131.52), member
# function template (184.108.40.206), or template specialization for which
# some template parameters are not specified (14.7, 14.5.4) in a
# program provided that each definition appears in a different
# translation unit, and provided the definitions satisfy the following
# requirements. Given such an entity named D defined in more than one
# translation unit, then
# - each definition of D shall consist of the same sequence of tokens;
# - in each definition of D, corresponding names, looked up according to
# 3.4, shall refer to an entity defined within the definition of D, or
# shall refer to the same entity, after overload resolution (13.3) and
# after matching of partial template specialization (14.8.3), except
# that a name can refer to a const object with internal or no linkage
# if the object has the same integral or enumeration type in all
# definitions of D,
# - ...
# If the definitions of D do not satisfy these requirements, then the
# behavior is undefined.
While you satisfy the first requirement (both definitions consist of
the same sequence of tokens), you fail to satisfy the second one: Both
definitions refer to "counter", but counter is a different entitity in
foo.cc, compared to bar.cc.
So according to the standard, your program has undefined
behaviour. That's why the compiler is allowed to give you one
behaviour with -O and another one when compiling without optimization.
More information about the Gcc-bugs