Bug 58738 - forward declaration of function inside function cause link problem with optimization
Summary: forward declaration of function inside function cause link problem with optim...
Status: UNCONFIRMED
Alias: None
Product: gcc
Classification: Unclassified
Component: c++ (show other bugs)
Version: unknown
: P3 normal
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords: link-failure
Depends on:
Blocks:
 
Reported: 2013-10-15 12:38 UTC by Evgeniy Dushistov
Modified: 2021-09-10 02:09 UTC (History)
2 users (show)

See Also:
Host:
Target:
Build:
Known to work: 11.1.0, 12.0
Known to fail: 10.1.0, 4.8.1, 9.1.0
Last reconfirmed:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Evgeniy Dushistov 2013-10-15 12:38:21 UTC
Here source code of test case:
namespace {

int foo()
{
	int bar(void);
	return bar();
}

int bar() { return -1; }

}

int main(int argc, char* argv[])
{
	return foo();
}

With g++ -O0 -Wpedantic -ansi -Wall test.cpp it compiles fine, while
with the same options except s/-O0/-O2/g it gave:
undefined reference to `(anonymous namespace)::bar()'.

gcc 4.8.1/amd64
Comment 1 Jonathan Wakely 2013-10-15 13:09:40 UTC
The standard says:

The name of a function declared in block scope and the name of a variable declared by a block scope extern declaration have linkage. If there is a visible declaration of an entity with linkage having the same name and type, ignoring entities declared outside the innermost enclosing namespace scope, the block scope declaration declares that same entity and receives the linkage of the previous declaration. If there is more than one such matching entity, the program is ill-formed. Otherwise, if no matching entity is found, the block scope entity
receives external linkage.

That means the first declaration of bar() has external linkage, but the later definition has internal linkage because it's a member of an unnamed namespace, so the declaration does not match the definition.

So I think your program is invalid.
Comment 2 Evgeniy Dushistov 2013-10-15 14:07:28 UTC
>That means the first declaration of bar() has external linkage, but the later >definition has internal linkage because it's a member of an unnamed namespace, >so the declaration does not match the definition.

But if gcc consider that bar() has external linkage,
(- When a name has external linkage, the enity it denotes can be referred to by names from scopes of other translation uits or from other scopes of the same translation unit.)

why it generate reference to  `(anonymous namespace)::bar()'?

According to error message it has anonymous namespace, in another words internal linkage.
Comment 3 Andrew Pinski 2021-09-10 00:00:55 UTC
This seems to have been fixed in GCC 11+.
Comment 4 Andrew Pinski 2021-09-10 00:04:15 UTC
I suspect maybe r11-3699 fixed this.