Inline Functions don't have Internal Linkage without -O option

Martin v. Loewis martin@mira.isdn.cs.tu-berlin.de
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
function.

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 (14.5.1.3), member
# function template (14.5.1.1), 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;
#   and
# - 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.

Regards,
Martin



More information about the Gcc-bugs mailing list