public inbox for gcc-bugs@sourceware.org
help / color / mirror / Atom feed
* [Bug c/49653] New: Undefined reference to inlined function with -O0,-std=c99
@ 2011-07-05 22:13 gary at intrepid dot com
  2011-07-05 22:16 ` [Bug c/49653] " pinskia at gcc dot gnu.org
                   ` (10 more replies)
  0 siblings, 11 replies; 12+ messages in thread
From: gary at intrepid dot com @ 2011-07-05 22:13 UTC (permalink / raw)
  To: gcc-bugs

http://gcc.gnu.org/bugzilla/show_bug.cgi?id=49653

           Summary: Undefined reference to inlined function with
                    -O0,-std=c99
           Product: gcc
           Version: 4.5.1
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c
        AssignedTo: unassigned@gcc.gnu.org
        ReportedBy: gary@intrepid.com


Given,

$ cat -n inline_trouble.c
     1  inline long trouble(long a, long b)
     2  {
     3      return a + b;
     4  }
     5
     6  long two = 2;
     7
     8  int main()
     9  {
    10      long result = trouble(two, two);
    11      return (int)result;
    12  }

$ gcc --version
gcc (GCC) 4.5.1 20100924 (Red Hat 4.5.1-4)

This test compiles and links cleanly at -O2,-std=c99:

$ gcc  -std=c99 -O2 inline_trouble.c

At -O0 -std=c99, it fails to link.

$ gcc  -std=c99 -O0 inline_trouble.c
/tmp/ccXya7LE.o: In function `main':
inline_trouble.c:(.text+0x1d): undefined reference to `trouble'
collect2: ld returned 1 exit status

Note that gnu90 doesn't have this issue.

$ gcc  -std=gnu90 -O0 inline_trouble.c

(Although GCC 4.5.1 is used in the test above, it is likely that this problem
can be reproduced with GCC built from the trunk.)


^ permalink raw reply	[flat|nested] 12+ messages in thread

* [Bug c/49653] Undefined reference to inlined function with -O0,-std=c99
  2011-07-05 22:13 [Bug c/49653] New: Undefined reference to inlined function with -O0,-std=c99 gary at intrepid dot com
@ 2011-07-05 22:16 ` pinskia at gcc dot gnu.org
  2011-07-06  5:28 ` schaub.johannes at googlemail dot com
                   ` (9 subsequent siblings)
  10 siblings, 0 replies; 12+ messages in thread
From: pinskia at gcc dot gnu.org @ 2011-07-05 22:16 UTC (permalink / raw)
  To: gcc-bugs

http://gcc.gnu.org/bugzilla/show_bug.cgi?id=49653

--- Comment #1 from Andrew Pinski <pinskia at gcc dot gnu.org> 2011-07-05 22:15:54 UTC ---
This is correct for C99.  inline alone in C99 is the same GNU's C90's extern
inline.


^ permalink raw reply	[flat|nested] 12+ messages in thread

* [Bug c/49653] Undefined reference to inlined function with -O0,-std=c99
  2011-07-05 22:13 [Bug c/49653] New: Undefined reference to inlined function with -O0,-std=c99 gary at intrepid dot com
  2011-07-05 22:16 ` [Bug c/49653] " pinskia at gcc dot gnu.org
@ 2011-07-06  5:28 ` schaub.johannes at googlemail dot com
  2011-07-06  8:10 ` rguenth at gcc dot gnu.org
                   ` (8 subsequent siblings)
  10 siblings, 0 replies; 12+ messages in thread
From: schaub.johannes at googlemail dot com @ 2011-07-06  5:28 UTC (permalink / raw)
  To: gcc-bugs

http://gcc.gnu.org/bugzilla/show_bug.cgi?id=49653

Johannes Schaub <schaub.johannes at googlemail dot com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |schaub.johannes at
                   |                            |googlemail dot com

--- Comment #2 from Johannes Schaub <schaub.johannes at googlemail dot com> 2011-07-06 05:27:41 UTC ---
(In reply to comment #1)
> This is correct for C99.  inline alone in C99 is the same GNU's C90's extern
> inline.

For an explanation, see
http://stackoverflow.com/questions/2217628/multiple-definition-of-inline-functions-when-linking-static-libs/2218034#2218034
. In particular

  "In a call to an inline function it's unspecified whether the external or the
inline definition is used."


^ permalink raw reply	[flat|nested] 12+ messages in thread

* [Bug c/49653] Undefined reference to inlined function with -O0,-std=c99
  2011-07-05 22:13 [Bug c/49653] New: Undefined reference to inlined function with -O0,-std=c99 gary at intrepid dot com
  2011-07-05 22:16 ` [Bug c/49653] " pinskia at gcc dot gnu.org
  2011-07-06  5:28 ` schaub.johannes at googlemail dot com
@ 2011-07-06  8:10 ` rguenth at gcc dot gnu.org
  2011-07-06 17:29 ` gary at intrepid dot com
                   ` (7 subsequent siblings)
  10 siblings, 0 replies; 12+ messages in thread
From: rguenth at gcc dot gnu.org @ 2011-07-06  8:10 UTC (permalink / raw)
  To: gcc-bugs

http://gcc.gnu.org/bugzilla/show_bug.cgi?id=49653

Richard Guenther <rguenth at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|UNCONFIRMED                 |RESOLVED
         Resolution|                            |INVALID

--- Comment #3 from Richard Guenther <rguenth at gcc dot gnu.org> 2011-07-06 08:10:20 UTC ---
.


^ permalink raw reply	[flat|nested] 12+ messages in thread

* [Bug c/49653] Undefined reference to inlined function with -O0,-std=c99
  2011-07-05 22:13 [Bug c/49653] New: Undefined reference to inlined function with -O0,-std=c99 gary at intrepid dot com
                   ` (2 preceding siblings ...)
  2011-07-06  8:10 ` rguenth at gcc dot gnu.org
@ 2011-07-06 17:29 ` gary at intrepid dot com
  2011-07-06 19:21 ` gary at intrepid dot com
                   ` (6 subsequent siblings)
  10 siblings, 0 replies; 12+ messages in thread
From: gary at intrepid dot com @ 2011-07-06 17:29 UTC (permalink / raw)
  To: gcc-bugs

http://gcc.gnu.org/bugzilla/show_bug.cgi?id=49653

--- Comment #4 from Gary Funck <gary at intrepid dot com> 2011-07-06 17:29:32 UTC ---
Thanks Andrew and Johannes for the follow-up.  The difference in between
optimized and non-optimized compilations was surprising to me, but I now
understand that this is the result of the way that GCC handles this
implementation-defined behavior.


^ permalink raw reply	[flat|nested] 12+ messages in thread

* [Bug c/49653] Undefined reference to inlined function with -O0,-std=c99
  2011-07-05 22:13 [Bug c/49653] New: Undefined reference to inlined function with -O0,-std=c99 gary at intrepid dot com
                   ` (3 preceding siblings ...)
  2011-07-06 17:29 ` gary at intrepid dot com
@ 2011-07-06 19:21 ` gary at intrepid dot com
  2011-07-06 19:37 ` redi at gcc dot gnu.org
                   ` (5 subsequent siblings)
  10 siblings, 0 replies; 12+ messages in thread
From: gary at intrepid dot com @ 2011-07-06 19:21 UTC (permalink / raw)
  To: gcc-bugs

http://gcc.gnu.org/bugzilla/show_bug.cgi?id=49653

--- Comment #5 from Gary Funck <gary at intrepid dot com> 2011-07-06 19:21:26 UTC ---
Would the following make sense as an enhancement, and still be standards
conforming?

RFE: If compiling in C99 mode at -O0 (optimization disabled), compile functions
declared as "inline" as if they were instead declared "static".

In this way, if a user makes use of inlined functions, but decides to
re-compile his program at -O0 (in C99 mode) he doesn't have to resort to using
work-arounds (such as compiling with -Dinline=static").


^ permalink raw reply	[flat|nested] 12+ messages in thread

* [Bug c/49653] Undefined reference to inlined function with -O0,-std=c99
  2011-07-05 22:13 [Bug c/49653] New: Undefined reference to inlined function with -O0,-std=c99 gary at intrepid dot com
                   ` (4 preceding siblings ...)
  2011-07-06 19:21 ` gary at intrepid dot com
@ 2011-07-06 19:37 ` redi at gcc dot gnu.org
  2011-07-07 16:38 ` gary at intrepid dot com
                   ` (4 subsequent siblings)
  10 siblings, 0 replies; 12+ messages in thread
From: redi at gcc dot gnu.org @ 2011-07-06 19:37 UTC (permalink / raw)
  To: gcc-bugs

http://gcc.gnu.org/bugzilla/show_bug.cgi?id=49653

--- Comment #6 from Jonathan Wakely <redi at gcc dot gnu.org> 2011-07-06 19:37:00 UTC ---
why not just add this to make the code valid by emitting an extern definition?

extern long trouble(long, long);


^ permalink raw reply	[flat|nested] 12+ messages in thread

* [Bug c/49653] Undefined reference to inlined function with -O0,-std=c99
  2011-07-05 22:13 [Bug c/49653] New: Undefined reference to inlined function with -O0,-std=c99 gary at intrepid dot com
                   ` (5 preceding siblings ...)
  2011-07-06 19:37 ` redi at gcc dot gnu.org
@ 2011-07-07 16:38 ` gary at intrepid dot com
  2011-07-07 16:49 ` redi at gcc dot gnu.org
                   ` (3 subsequent siblings)
  10 siblings, 0 replies; 12+ messages in thread
From: gary at intrepid dot com @ 2011-07-07 16:38 UTC (permalink / raw)
  To: gcc-bugs

http://gcc.gnu.org/bugzilla/show_bug.cgi?id=49653

--- Comment #7 from Gary Funck <gary at intrepid dot com> 2011-07-07 16:38:33 UTC ---
(In reply to comment #6)
> why not just add this to make the code valid by emitting an extern definition?
> 
> extern long trouble(long, long);

If you're suggesting that the front-end would do this automatically when
compiling -O0 -std={gnu}99, I'd agree that this would be a good way to handle
this use case.


^ permalink raw reply	[flat|nested] 12+ messages in thread

* [Bug c/49653] Undefined reference to inlined function with -O0,-std=c99
  2011-07-05 22:13 [Bug c/49653] New: Undefined reference to inlined function with -O0,-std=c99 gary at intrepid dot com
                   ` (6 preceding siblings ...)
  2011-07-07 16:38 ` gary at intrepid dot com
@ 2011-07-07 16:49 ` redi at gcc dot gnu.org
  2011-07-07 16:56 ` gary at intrepid dot com
                   ` (2 subsequent siblings)
  10 siblings, 0 replies; 12+ messages in thread
From: redi at gcc dot gnu.org @ 2011-07-07 16:49 UTC (permalink / raw)
  To: gcc-bugs

http://gcc.gnu.org/bugzilla/show_bug.cgi?id=49653

--- Comment #8 from Jonathan Wakely <redi at gcc dot gnu.org> 2011-07-07 16:49:18 UTC ---
(In reply to comment #7)
> (In reply to comment #6)
> > why not just add this to make the code valid by emitting an extern definition?
> > 
> > extern long trouble(long, long);
> 
> If you're suggesting that the front-end would do this automatically when
> compiling -O0 -std={gnu}99, I'd agree that this would be a good way to handle
> this use case.

No, I was suggesting you add it, not the compiler.


^ permalink raw reply	[flat|nested] 12+ messages in thread

* [Bug c/49653] Undefined reference to inlined function with -O0,-std=c99
  2011-07-05 22:13 [Bug c/49653] New: Undefined reference to inlined function with -O0,-std=c99 gary at intrepid dot com
                   ` (7 preceding siblings ...)
  2011-07-07 16:49 ` redi at gcc dot gnu.org
@ 2011-07-07 16:56 ` gary at intrepid dot com
  2011-07-07 17:09 ` redi at gcc dot gnu.org
  2011-07-07 19:01 ` gary at intrepid dot com
  10 siblings, 0 replies; 12+ messages in thread
From: gary at intrepid dot com @ 2011-07-07 16:56 UTC (permalink / raw)
  To: gcc-bugs

http://gcc.gnu.org/bugzilla/show_bug.cgi?id=49653

--- Comment #9 from Gary Funck <gary at intrepid dot com> 2011-07-07 16:55:38 UTC ---
(In reply to comment #8)
> (In reply to comment #7)
> GF: If you're suggesting that the front-end would do this automatically when
> GF: compiling -O0 -std={gnu}99, I'd agree that this would be a good way to handle
> GF: this use case.
> 
> No, I was suggesting you add it, not the compiler.

OK.  That would be a different use case.


^ permalink raw reply	[flat|nested] 12+ messages in thread

* [Bug c/49653] Undefined reference to inlined function with -O0,-std=c99
  2011-07-05 22:13 [Bug c/49653] New: Undefined reference to inlined function with -O0,-std=c99 gary at intrepid dot com
                   ` (8 preceding siblings ...)
  2011-07-07 16:56 ` gary at intrepid dot com
@ 2011-07-07 17:09 ` redi at gcc dot gnu.org
  2011-07-07 19:01 ` gary at intrepid dot com
  10 siblings, 0 replies; 12+ messages in thread
From: redi at gcc dot gnu.org @ 2011-07-07 17:09 UTC (permalink / raw)
  To: gcc-bugs

http://gcc.gnu.org/bugzilla/show_bug.cgi?id=49653

--- Comment #10 from Jonathan Wakely <redi at gcc dot gnu.org> 2011-07-07 17:08:54 UTC ---
The point is your code is invalid and the compiler's behaviour at -O0 is
correct.

C99 6.9 "If an identifier declared with external linkage is used in an
expression (other than as part of the operand of a sizeof operator whose result
is an integer constant), somewhere in the entire program there shall be exactly
one external definition for the identifier; otherwise, there shall be no more
than
one."

You get away with the invalid program with optimisation but that doesn't make
it correct. If the compiler decided not to inline the function because of its
size or the amount of inlining it had already done, or a user compiled the code
with -fno-inline-functions -O3, then the code would fail to link again.

The solution is not to modify the compiler, but to fix the code. Either make
the function static (so no external definition is needed) or ensure an external
definition is present in some translation unit (or as a GNU extension mark it
"always_inline" so you get away without referencing the external definition.)


^ permalink raw reply	[flat|nested] 12+ messages in thread

* [Bug c/49653] Undefined reference to inlined function with -O0,-std=c99
  2011-07-05 22:13 [Bug c/49653] New: Undefined reference to inlined function with -O0,-std=c99 gary at intrepid dot com
                   ` (9 preceding siblings ...)
  2011-07-07 17:09 ` redi at gcc dot gnu.org
@ 2011-07-07 19:01 ` gary at intrepid dot com
  10 siblings, 0 replies; 12+ messages in thread
From: gary at intrepid dot com @ 2011-07-07 19:01 UTC (permalink / raw)
  To: gcc-bugs

http://gcc.gnu.org/bugzilla/show_bug.cgi?id=49653

--- Comment #11 from Gary Funck <gary at intrepid dot com> 2011-07-07 19:01:19 UTC ---
Thanks for the additional info.  I agree that it would be incorrect for the
compiler to default to "extern" if it chooses not to inline the function (I
hadn't thought that suggestion through.)

My reason for filing this bug report was to point out that the program
compilation behaves differently with and without optimization enabled.  As a
general rule, I think it is better that GCC's behavior does not change between
varying levels of optimization.

For example, let's say that when GCC chooses to inline this C99 defined
"inline" function, that it also emits an external reference to the named
routine.  Then at link time, if no external definition is found, the link would
fail, in a manner similar to the way that it does at -O0.  IMO, that would be a
better situation than now, because the tool chain's behavior is consistent
across optimization levels.  Of course, in both cases, it would be better if a
more helpful error message is supplied.

Based on the discussion of the C99 definition of "inline", cited by Johannes
Schaub, the compiler is free to choose whether to use the inline definition or
to generate an external reference.  Thus, if we focus only on the translation
unit, it seems that GCC could choose to compile the "inline" function as if it
had been declared "static" when compiling in C99 mode with inlining disabled. 
This is no worse, it would seem, than inlining the function at higher levels of
optimization, and not checking that an external definition for the function is
defined somewhere in the linked program.


^ permalink raw reply	[flat|nested] 12+ messages in thread

end of thread, other threads:[~2011-07-07 19:01 UTC | newest]

Thread overview: 12+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2011-07-05 22:13 [Bug c/49653] New: Undefined reference to inlined function with -O0,-std=c99 gary at intrepid dot com
2011-07-05 22:16 ` [Bug c/49653] " pinskia at gcc dot gnu.org
2011-07-06  5:28 ` schaub.johannes at googlemail dot com
2011-07-06  8:10 ` rguenth at gcc dot gnu.org
2011-07-06 17:29 ` gary at intrepid dot com
2011-07-06 19:21 ` gary at intrepid dot com
2011-07-06 19:37 ` redi at gcc dot gnu.org
2011-07-07 16:38 ` gary at intrepid dot com
2011-07-07 16:49 ` redi at gcc dot gnu.org
2011-07-07 16:56 ` gary at intrepid dot com
2011-07-07 17:09 ` redi at gcc dot gnu.org
2011-07-07 19:01 ` gary at intrepid dot com

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).