Issue Details (XML | Word | Printable)

Key: PCC-287
Type: Bug Bug
Status: Resolved Resolved
Resolution: Fixed
Priority: Major Major
Assignee: Anders Magnusson
Reporter: Iain Hibbert
Votes: 0
Watchers: 1
Operations

If you were logged in you would be able to see more operations.
pcc

inline function with external declaration does not create external linkage

Created: 27/Mar/11 10:21 PM   Updated: 31/Jul/12 11:01 AM
Component/s: C frontend
Affects Version/s: None
Fix Version/s: None

Environment: NetBSD/i386


 Description  « Hide
The following example

extern void foo (void); /* declaration */

inline void foo (void) /* definition */
{
}

does not create a foo linkage in the output file, whereas if the declaration follows the definition it does. Interestingly, if a declaration appears both before and after the function then no symbol is emitted either.

I'm not completely sure but I think this is a bug. Even though the C99 spec shows an example with the declaration following the definition (6.7.4 note 7) I can't see that it is useful to restrict it to such an eventuality.. considering the (I guess, usual) case where the function prototype is in a system header file, the function appears in a C module and it is desired to inline it there and yet provide external linkage it becomes difficult to do so if you must place the external declaration (the prototype) before the definition.

 All   Comments   Change History      Sort Order: Ascending order - Click to sort in descending order
Anders Magnusson added a comment - 29/Mar/11 06:46 PM
The standard for inline functions is tricky at least. I think the current behavior is conforming, even though it may not be the most expected behavior.
This is a side-effect of the way inline is handled in the compiler.

To provide both external and internal linkage after a declaration add "extern" to the definition:
extern void foo (void); /* declaration */

extern inline void foo (void) /* definition */
{
}


Iain Hibbert added a comment - 30/Mar/11 11:12 AM
I think the extern on the definition should not be required, according to C99 specification.. and I'm trying to avoid it as it conflicts with gcc (this is the tricky bit :)

if we accept that the following

inline void foo (void)
{
}

extern void foo (void);

is required to produce an external linkage (this is the example given, and it does work with pcc) then I think that perhaps the following

void foo(void);

inline void foo(void)
{
}

extern void foo (void);

should also provide the linkage.. no?

Anders Magnusson added a comment - 30/Mar/11 12:14 PM
Gcc model newer should have the same behavior as pcc if set to -std=c99.
I assume that the problem here is that pcc does not obey -std=gnu99, which it should.

...at least, either that or converting all inline functions to just static inline.

Anders Magnusson added a comment - 30/Jul/12 07:37 PM
Is this bug report still useful? I cannot get anything out of it :-)

Iain Hibbert added a comment - 31/Jul/12 09:50 AM
Well, there is a difference in output that I am not convinced is correct :-)

% cat foo.c
void foo (void);

inline void foo (void)
{
}

extern void foo (void);

% pcc -c foo.c && nm foo.o
% pcc --version
pcc 1.1.0.DEVEL 20120730 for netbsd-i386

% gcc -c foo.c && nm foo.o
00000000 T foo
% gcc -std=c99 -c foo.c && nm foo.o
00000000 T foo
% gcc --version
gcc (NetBSD nb2 20110806) 4.5.3
Copyright (C) 2010 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.


having said that, I don't have a note of where I found this to be a problem which means that it is likely not an actual problem and this issue could be closed without consequences..

Anders Magnusson added a comment - 31/Jul/12 11:01 AM
Now pcc should act the same independent of whether extern is given before or after the declaration.
This is the same way as gcc deals with this issue.