public inbox for gcc-bugs@sourceware.org
help / color / mirror / Atom feed
* [Bug c++/46589] New: struct member function not declared global
@ 2010-11-21 13:21 temptony at freemail dot hu
  2010-11-21 18:04 ` [Bug c++/46589] " redi at gcc dot gnu.org
                   ` (8 more replies)
  0 siblings, 9 replies; 10+ messages in thread
From: temptony at freemail dot hu @ 2010-11-21 13:21 UTC (permalink / raw)
  To: gcc-bugs

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

           Summary: struct member function not declared global
           Product: gcc
           Version: 4.4.0
            Status: UNCONFIRMED
          Severity: minor
          Priority: P3
         Component: c++
        AssignedTo: unassigned@gcc.gnu.org
        ReportedBy: temptony@freemail.hu


Summary of bug:

g++ doesn't declare L::G() global in the following code:
  typedef struct { void G() ; } L ;
  void L::G() { }

although it does here ('typedef struct L' instead of 'typedef struct'):
  typedef struct L { void G() ; } L ;
  void L::G() { }

Output from gcc -v:

  Using built-in specs.
  Target: mingw32
  Configured with: ../gcc-4.4.0/configure
--enable-languages=c,ada,c++,fortran,java,objc,obj-c++ --dis
  able-sjlj-exceptions --enable-shared --enable-libgcj --enable-libgomp
--with-dwarf2 --disable-win32-
  registry --enable-libstdcxx-debug --enable-version-specific-runtime-libs
--prefix=/mingw --with-gmp=
  /mingw/src/gmp/root --with-mpfr=/mingw/src/mpfr/root --build=mingw32
  Thread model: win32
  gcc version 4.4.0 (GCC)

File main.cpp:

  typedef struct { void G() ; } L ;
  static L X ;
  int main() { X.G() ; }

File L0.cpp:

  typedef struct { void G() ; } L ;
  void L::G() { }

The command:

  g++ main.cpp L0.cpp

This fails with:

  C:\...\Temp\ccCl8AUu.o:main.cpp:(.text+0x16): undefined reference to `L::G()'
  collect2: ld returned 1 exit status

BUT: File L1.cpp has 'typedef struct' instead of 'typedef struct L':

  typedef struct L { void G() ; } L ;
  void L::G() { }

  g++ main.cpp L1.cpp

This works!

The difference can be seen in the assembly output:

    .file    "L0.cpp"
    .text
    .align 2
    .def    __ZN1L1GEv;    .scl    3;    .type    32;    .endef
__ZN1L1GEv:
LFB0:
    pushl    %ebp
LCFI0:
    movl    %esp, %ebp
LCFI1:
    leave
    ret
LFE0:

    .file    "L1.cpp"
    .text
    .align 2
.globl __ZN1L1GEv
    .def    __ZN1L1GEv;    .scl    2;    .type    32;    .endef
__ZN1L1GEv:
LFB0:
    pushl    %ebp
LCFI0:
    movl    %esp, %ebp
LCFI1:
    leave
    ret
LFE0:

__ZN1L1GEv is not declared global in L0.s.


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

* [Bug c++/46589] struct member function not declared global
  2010-11-21 13:21 [Bug c++/46589] New: struct member function not declared global temptony at freemail dot hu
@ 2010-11-21 18:04 ` redi at gcc dot gnu.org
  2010-11-21 22:42 ` paolo.carlini at oracle dot com
                   ` (7 subsequent siblings)
  8 siblings, 0 replies; 10+ messages in thread
From: redi at gcc dot gnu.org @ 2010-11-21 18:04 UTC (permalink / raw)
  To: gcc-bugs

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

--- Comment #1 from Jonathan Wakely <redi at gcc dot gnu.org> 2010-11-21 17:51:27 UTC ---
typedef struct { void G() ; } L ;
void L::G() { }

This is not the same type as L in main.cpp and the error is correct, L::G is
not defined

What you've defined is {unnamed type in L0.cpp}::G and that's not the same
function as {type L in main.cpp}::G

it's confusing because you've used the typedef L in both files, but that
doesn't make it the same type, and more than this would:

// file1.cpp
typedef struct X { void f(); } L;

// file2.cpp
typedef struct Y { void g(); } L;

Clearly you have two different typedefs called L here (which is an ODR
violation) and not a single type.


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

* [Bug c++/46589] struct member function not declared global
  2010-11-21 13:21 [Bug c++/46589] New: struct member function not declared global temptony at freemail dot hu
  2010-11-21 18:04 ` [Bug c++/46589] " redi at gcc dot gnu.org
@ 2010-11-21 22:42 ` paolo.carlini at oracle dot com
  2010-11-21 23:17 ` redi at gcc dot gnu.org
                   ` (6 subsequent siblings)
  8 siblings, 0 replies; 10+ messages in thread
From: paolo.carlini at oracle dot com @ 2010-11-21 22:42 UTC (permalink / raw)
  To: gcc-bugs

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

Paolo Carlini <paolo.carlini at oracle dot com> changed:

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

--- Comment #2 from Paolo Carlini <paolo.carlini at oracle dot com> 2010-11-21 22:16:34 UTC ---
Let's close this then.


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

* [Bug c++/46589] struct member function not declared global
  2010-11-21 13:21 [Bug c++/46589] New: struct member function not declared global temptony at freemail dot hu
  2010-11-21 18:04 ` [Bug c++/46589] " redi at gcc dot gnu.org
  2010-11-21 22:42 ` paolo.carlini at oracle dot com
@ 2010-11-21 23:17 ` redi at gcc dot gnu.org
  2010-11-22  1:39 ` temptony at freemail dot hu
                   ` (5 subsequent siblings)
  8 siblings, 0 replies; 10+ messages in thread
From: redi at gcc dot gnu.org @ 2010-11-21 23:17 UTC (permalink / raw)
  To: gcc-bugs

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

--- Comment #3 from Jonathan Wakely <redi at gcc dot gnu.org> 2010-11-21 23:14:45 UTC ---
There might still be a bug here, just not demonstrated very well by the
original testcase.  Here's a version where the definitions of S agree, but gcc
still defines S::f as local and so the program fails to link:

// file1.cc
typedef struct { int f(); } S;

int main()
{
  S s;
  return s.f();
}

// file2.cc
typedef struct { int f(); } S;

int S::f() { return 0; }

I'm not sure if [basic.link] paragraph 5 means S::f should have external
linkage or not. Paragraph 4 (third bullet) means that S has external linkage.
Paragraph 5 refers to the name of the class and in this case the class has no
name, but it has the typedef name for linkage purposes.  I'm not sure if that
means S::f should or should not have external linkage.


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

* [Bug c++/46589] struct member function not declared global
  2010-11-21 13:21 [Bug c++/46589] New: struct member function not declared global temptony at freemail dot hu
                   ` (2 preceding siblings ...)
  2010-11-21 23:17 ` redi at gcc dot gnu.org
@ 2010-11-22  1:39 ` temptony at freemail dot hu
  2010-11-22  3:48 ` paolo.carlini at oracle dot com
                   ` (4 subsequent siblings)
  8 siblings, 0 replies; 10+ messages in thread
From: temptony at freemail dot hu @ 2010-11-22  1:39 UTC (permalink / raw)
  To: gcc-bugs

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

--- Comment #4 from TonyK <temptony at freemail dot hu> 2010-11-22 00:19:18 UTC ---
(In reply to comment #3)
> There might still be a bug here, just not demonstrated very well by the
> original testcase.  Here's a version where the definitions of S agree, but gcc
> still defines S::f as local and so the program fails to link:
> 
> // file1.cc
> typedef struct { int f(); } S;
> 
> int main()
> {
>   S s;
>   return s.f();
> }
> 
> // file2.cc
> typedef struct { int f(); } S;
> 
> int S::f() { return 0; }

This is exactly the same as my original submission, isn't it?


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

* [Bug c++/46589] struct member function not declared global
  2010-11-21 13:21 [Bug c++/46589] New: struct member function not declared global temptony at freemail dot hu
                   ` (3 preceding siblings ...)
  2010-11-22  1:39 ` temptony at freemail dot hu
@ 2010-11-22  3:48 ` paolo.carlini at oracle dot com
  2010-11-22  8:50 ` redi at gcc dot gnu.org
                   ` (3 subsequent siblings)
  8 siblings, 0 replies; 10+ messages in thread
From: paolo.carlini at oracle dot com @ 2010-11-22  3:48 UTC (permalink / raw)
  To: gcc-bugs

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

Paolo Carlini <paolo.carlini at oracle dot com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|RESOLVED                    |REOPENED
   Last reconfirmed|                            |2010.11.22 01:39:44
         Resolution|INVALID                     |
     Ever Confirmed|0                           |1
           Severity|minor                       |normal

--- Comment #5 from Paolo Carlini <paolo.carlini at oracle dot com> 2010-11-22 01:39:44 UTC ---
Oops, let's reopen this.


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

* [Bug c++/46589] struct member function not declared global
  2010-11-21 13:21 [Bug c++/46589] New: struct member function not declared global temptony at freemail dot hu
                   ` (4 preceding siblings ...)
  2010-11-22  3:48 ` paolo.carlini at oracle dot com
@ 2010-11-22  8:50 ` redi at gcc dot gnu.org
  2011-01-02 14:29 ` ktietz at gcc dot gnu.org
                   ` (2 subsequent siblings)
  8 siblings, 0 replies; 10+ messages in thread
From: redi at gcc dot gnu.org @ 2010-11-22  8:50 UTC (permalink / raw)
  To: gcc-bugs

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

--- Comment #6 from Jonathan Wakely <redi at gcc dot gnu.org> 2010-11-22 08:47:42 UTC ---
(In reply to comment #4)
> This is exactly the same as my original submission, isn't it?

Yes sorry, I mixed up the first two code snippets with the code from main.cpp
and L0.cpp, but they are different. Apologies


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

* [Bug c++/46589] struct member function not declared global
  2010-11-21 13:21 [Bug c++/46589] New: struct member function not declared global temptony at freemail dot hu
                   ` (5 preceding siblings ...)
  2010-11-22  8:50 ` redi at gcc dot gnu.org
@ 2011-01-02 14:29 ` ktietz at gcc dot gnu.org
  2011-01-02 17:23 ` hjl.tools at gmail dot com
  2021-08-05 11:33 ` redi at gcc dot gnu.org
  8 siblings, 0 replies; 10+ messages in thread
From: ktietz at gcc dot gnu.org @ 2011-01-02 14:29 UTC (permalink / raw)
  To: gcc-bugs

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

Kai Tietz <ktietz at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |ktietz at gcc dot gnu.org

--- Comment #7 from Kai Tietz <ktietz at gcc dot gnu.org> 2011-01-02 14:29:18 UTC ---
(In reply to comment #3)
> I'm not sure if [basic.link] paragraph 5 means S::f should have external
> linkage or not. Paragraph 4 (third bullet) means that S has external linkage.
> Paragraph 5 refers to the name of the class and in this case the class has no
> name, but it has the typedef name for linkage purposes.  I'm not sure if that
> means S::f should or should not have external linkage.

As far as I understand specificiation (C++ Standard - ANSI ISO IEC 14882 2003)

3.5 Program and linkage 3 Basic concepts

--- an object or reference that is explicitly declared const and neither
explicitly declared extern nor
previously declared to have external linkage; or
--- a data member of an anonymous union.

4 A name having namespace scope has external linkage if it is the name of
--- an object or reference, unless it has internal linkage; or
--- a function, unless it has internal linkage; or
--- a named class (clause 9), or an unnamed class defined in a typedef
declaration in which the class has the
typedef name for linkage purposes (7.1.3); or
--- a named enumeration (7.2), or an unnamed enumeration defined in a typedef
declaration in which the
enumeration has the typedef name for linkage purposes (7.1.3); or
--- an enumerator belonging to an enumeration with external linkage; or
--- a template, unless it is a function template that has internal linkage
(clause 14); or
--- a namespace (7.3), unless it is declared within an unnamed namespace.

5 In addition, a member function, static data member, class or enumeration of
class scope has external linkage
if the name of the class has external linkage.

7.1.3
...
If the typedef declaration defines an unnamed class (or enum), the first
typedef-name declared by the declaration
to be that class type (or enum type) is used to denote the class type (or enum
type) for linkage purposes
only (3.5).
[Example:]
typedef struct { } *ps, S; // S is the class name for linkage purposes
[end example]
...

So S becomes here class name and the class S has external linkage. So member
functions of it, too. Just explicit constructor/destructors aren't possible
here, as S() would be a normal method and needs a return type.

Kai


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

* [Bug c++/46589] struct member function not declared global
  2010-11-21 13:21 [Bug c++/46589] New: struct member function not declared global temptony at freemail dot hu
                   ` (6 preceding siblings ...)
  2011-01-02 14:29 ` ktietz at gcc dot gnu.org
@ 2011-01-02 17:23 ` hjl.tools at gmail dot com
  2021-08-05 11:33 ` redi at gcc dot gnu.org
  8 siblings, 0 replies; 10+ messages in thread
From: hjl.tools at gmail dot com @ 2011-01-02 17:23 UTC (permalink / raw)
  To: gcc-bugs

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

H.J. Lu <hjl.tools at gmail dot com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |hjl.tools at gmail dot com

--- Comment #8 from H.J. Lu <hjl.tools at gmail dot com> 2011-01-02 17:23:42 UTC ---
ICC generates:

0000000000000000 T _ZN1L1GEv


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

* [Bug c++/46589] struct member function not declared global
  2010-11-21 13:21 [Bug c++/46589] New: struct member function not declared global temptony at freemail dot hu
                   ` (7 preceding siblings ...)
  2011-01-02 17:23 ` hjl.tools at gmail dot com
@ 2021-08-05 11:33 ` redi at gcc dot gnu.org
  8 siblings, 0 replies; 10+ messages in thread
From: redi at gcc dot gnu.org @ 2021-08-05 11:33 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=46589

--- Comment #9 from Jonathan Wakely <redi at gcc dot gnu.org> ---
This code was made ill-formed by https://wg21.link/p1766r1 (new in C++20 but a
DR against previous standards).

So GCC should just reject it (maybe with a switch to allow the old behaviour).
See PR 97475.

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

end of thread, other threads:[~2021-08-05 11:33 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2010-11-21 13:21 [Bug c++/46589] New: struct member function not declared global temptony at freemail dot hu
2010-11-21 18:04 ` [Bug c++/46589] " redi at gcc dot gnu.org
2010-11-21 22:42 ` paolo.carlini at oracle dot com
2010-11-21 23:17 ` redi at gcc dot gnu.org
2010-11-22  1:39 ` temptony at freemail dot hu
2010-11-22  3:48 ` paolo.carlini at oracle dot com
2010-11-22  8:50 ` redi at gcc dot gnu.org
2011-01-02 14:29 ` ktietz at gcc dot gnu.org
2011-01-02 17:23 ` hjl.tools at gmail dot com
2021-08-05 11:33 ` redi at gcc dot gnu.org

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).