public inbox for gcc-prs@sourceware.org
help / color / mirror / Atom feed
* Re: c++/9881: Incorrect address calculation for static class member
@ 2003-02-27 21:46 Peter A. Buhr
  0 siblings, 0 replies; 9+ messages in thread
From: Peter A. Buhr @ 2003-02-27 21:46 UTC (permalink / raw)
  To: nobody; +Cc: gcc-prs

The following reply was made to PR c++/9881; it has been noted by GNATS.

From: "Peter A. Buhr" <pabuhr@plg2.math.uwaterloo.ca>
To: bangerth@dealii.org, gcc-bugs@gcc.gnu.org, gcc-gnats@gcc.gnu.org
Cc: asharji@uwaterloo.ca
Subject: Re: c++/9881: Incorrect address calculation for static class member
Date: Thu, 27 Feb 2003 16:39:14 -0500 (EST)

    Synopsis: Incorrect address calculation for static class member
 
    State-Changed-From-To: open->closed
    State-Changed-By: bangerth
    State-Changed-When: Thu Feb 27 18:22:41 2003
    State-Changed-Why:
        In this code,
 	 foo f; // print output
 
 	 double *module::b = &(((bar *)&module::storage)->p);
 	 double module::storage = 0.0;
 
        The constructor of foo is run before module::b is initialized.
        If you change this order, the output is as you expect.
 
        W.
 
    http://gcc.gnu.org/cgi-bin/gnatsweb.pl?cmd=view%20audit-trail&database=gcc&pr=9881
 
 Your response is incorrect. First, the program generates the correct result
 with gcc3.2. If you run the example with both gcc3.2 and gcc3.3, you will see
 that the output is different. Hence, one can conclude that either gcc3.2 or
 gcc3.3 is wrong. Second, when the example program is run with the SUN compiler,
 it generates the same output as for gcc3.2, indicating that the problem is
 probably in gcc3.3. Third, the position of the constructor has nothing to do
 with the assignment to a static variable. The expression to initialize the
 static variable "module::b" *MUST* be evaluated at compiler time. All static
 variables *MUST* be initialized before any constructor is run because a
 constructor can refer to these variables. Finally, your suggestion is not even
 a work-around, because the original problem occurred in separate compilation
 units, so the notion of moving the constructor in this case does not apply.
 
 It is slightly disconcerting that you should close this bug report without at
 least checking with the people that reported the problem.


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

* Re: c++/9881: Incorrect address calculation for static class member
@ 2003-03-02 22:16 Wolfgang Bangerth
  0 siblings, 0 replies; 9+ messages in thread
From: Wolfgang Bangerth @ 2003-03-02 22:16 UTC (permalink / raw)
  To: nobody; +Cc: gcc-prs

The following reply was made to PR c++/9881; it has been noted by GNATS.

From: Wolfgang Bangerth <bangerth@ticam.utexas.edu>
To: "Peter A. Buhr" <pabuhr@plg2.math.uwaterloo.ca>
Cc: asharji@uwaterloo.ca, <gcc-bugs@gcc.gnu.org>, <gcc-gnats@gcc.gnu.org>
Subject: Re: c++/9881: Incorrect address calculation for static class member
Date: Sun, 2 Mar 2003 16:06:41 -0600 (CST)

 > It seems to me that a cast to a pointer should always have the same meaning.
 > That is, when reinterpreting the bits, the meaning of those bits cannot imply a
 > static context in one case and a dynamic in another. That seems too bizarre.
 
 This I leave to ones more trained in C++ standard legalese.
 
 > So what is the next step? My code use to work with gcc 3.2 and now fails with
 > gcc 3.3. My understanding is that gcc3.3 is scheduled for release very soon and
 > I would like my code to work with it. What law firm do I need to hire to press
 > my case as it seems the issue is an open question for the current version of
 > g++. What if I get a note from Bjarne saying which way it's suppose to go?
 
 Then this would be one more in the list of 400 or so C++ reports where we
 know that gcc is doing the wrong thing. If your claim is right then this
 would be a regression -- that would raise the priority of the report, but
 doesn't imply any guarantees. You didn't pay for gcc you have no claim
 against it. If you really need to make your code run with gcc3.3, you have
 3 options:
 - you fix gcc
 - you pay someone to fix gcc
 - you work around it in your code.
 
 
 > However, the bottom-line is that I should not need to justify a legitimate use
 > for some feature in the language. (What a programmer wishes to do in the
 > privacy their own code is their business.) The feature is there for me to use,
 > and should work correctly (modulo the current outstanding legal question).
 
 True enough, modulo the thing about free software: it comes "as is", 
 without any guarantees.
 
 Sorry for not being of more help
   Wolfgang
 
 -------------------------------------------------------------------------
 Wolfgang Bangerth             email:            bangerth@ticam.utexas.edu
                               www: http://www.ticam.utexas.edu/~bangerth/
 
 


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

* Re: c++/9881: Incorrect address calculation for static class member
@ 2003-02-28 13:56 Peter A. Buhr
  0 siblings, 0 replies; 9+ messages in thread
From: Peter A. Buhr @ 2003-02-28 13:56 UTC (permalink / raw)
  To: nobody; +Cc: gcc-prs

The following reply was made to PR c++/9881; it has been noted by GNATS.

From: "Peter A. Buhr" <pabuhr@plg2.math.uwaterloo.ca>
To: bangerth@ticam.utexas.edu
Cc: asharji@uwaterloo.ca, gcc-bugs@gcc.gnu.org, gcc-gnats@gcc.gnu.org
Subject: Re: c++/9881: Incorrect address calculation for static class member
Date: Fri, 28 Feb 2003 08:49:50 -0500 (EST)

 Sorry, for the delay in responding, but Thursday evening is my guitar lesson so
 I had to head home early to prepare.
 
    Well, all the questions you raise boil down to the question: what is an 
    address constant expression. Apparently, the compiler chooses to consider 
    the initializer in line X to be one, while it doesn't for line Y. I cannot 
    answer the question further than what I did in my previous mail, apart 
    from the fact that line X has not cast (or, rather: a cast from one type 
    to itself), while line Y has a (reinterpret_)cast from type module to 
    incompatible type bar.
 
 It seems to me that a cast to a pointer should always have the same meaning.
 That is, when reinterpreting the bits, the meaning of those bits cannot imply a
 static context in one case and a dynamic in another. That seems too bizarre.
 
 So what is the next step? My code use to work with gcc 3.2 and now fails with
 gcc 3.3. My understanding is that gcc3.3 is scheduled for release very soon and
 I would like my code to work with it. What law firm do I need to hire to press
 my case as it seems the issue is an open question for the current version of
 g++. What if I get a note from Bjarne saying which way it's suppose to go?
 
    Just as an aside, independent of the validity of the PR in itself: why are 
    you making it so particularly hard for the compiler to decide this? You 
    are setting module::b to &module::storage; there is simple syntax to 
    achieve this goal than the one you use, no? :-)
 
 The program I submitted is the simplest case I could construct to illustrate
 (what I perceive) as an issue (lawyer speak). The real program is an extensive
 thread-library for C++, called uC++:
 
    http://plg.uwaterloo.ca/~usystem/uC++.html
 
 When the thread library is booting up, I need to initialize, by hand, a few
 fields in a static data-structure, which ultimately gets initialized by its
 constructor. That is, during the boot sequence there are mutually recursive
 reference issues that can best be resolved by temporarily making one data
 structure *appear* initialized so the first step can complete and then actually
 initializing the data structure in the second step. To do this, I need to
 statically insert an address and a non-zero value into 2 fields of the data
 structure. Now I can't declare an instance of the data structure because that
 triggers a call to its constructor, so I have to statically allocate a block of
 storage that is the size of the data structure, pretend the storage is the data
 structure, hit the storage with the necessary values, use those values at the
 start of the boot sequence so it looks initialized, and then run the
 constructor on the storage (new(storage) foo) to get the storage initialized.
 (You asked for this.)
 
 The fundamental reason for the mutually recursive references is that a thread
 library has to replace malloc/free to make them thread safe (no I do not and
 will not use pthreads). Now malloc is called during _start, while booting the
 C++ runtime, but my malloc thinks the thread library is running and accesses
 the data structure that I statically initialize. I could use an initialization
 flag that is checked for each malloc, but it is possible to eliminate the check
 if the boot sequence can be tricked. After the C++ runtime is started, my
 library can start and properly initialize the data structure.  Essentially,
 when boot strapping a system, it is necessary to perform some of these
 "unusual" operations. There are similar, but much more complex, issues when
 boot strapping an OS.
 
 However, the bottom-line is that I should not need to justify a legitimate use
 for some feature in the language. (What a programmer wishes to do in the
 privacy their own code is their business.) The feature is there for me to use,
 and should work correctly (modulo the current outstanding legal question). But
 I do not mind answering this question for inquiring minds. (Which is how you
 asked the question.)


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

* Re: c++/9881: Incorrect address calculation for static class member
@ 2003-02-27 23:16 Wolfgang Bangerth
  0 siblings, 0 replies; 9+ messages in thread
From: Wolfgang Bangerth @ 2003-02-27 23:16 UTC (permalink / raw)
  To: nobody; +Cc: gcc-prs

The following reply was made to PR c++/9881; it has been noted by GNATS.

From: Wolfgang Bangerth <bangerth@ticam.utexas.edu>
To: "Peter A. Buhr" <pabuhr@plg2.math.uwaterloo.ca>
Cc: asharji@uwaterloo.ca, <gcc-bugs@gcc.gnu.org>, <gcc-gnats@gcc.gnu.org>
Subject: Re: c++/9881: Incorrect address calculation for static class member
Date: Thu, 27 Feb 2003 17:09:09 -0600 (CST)

 >    bar v;
 >    double *module::b = &(((bar *)(&v))->p); // LINE X
 >    //double *module::b = &(((bar *)(&module::storage))->p); // LINE Y
 > 
 > If you run this with gcc3.3, the output is:
 > 
 > @awk[5]% a.out
 > 0x8049a50 0x8049a48
 > 
 > Now comment out LINE X, and uncomment LINE Y and run again getting output:
 > 
 > @awk[6]% a.out
 > 0x8049a78 0
 > 
 > Zero (0) is not an acceptable address.
 
 Well, zero is the value the standard prescribes of initial initialization, 
 i.e. before dynamic initializers are run.
 
 > BUT, the only different between these 2
 > lines is the chunk of storage for the object. Notice this has nothing to do
 > with the constructor. One case works and one doesn't. Is this not compelling?
 
 Well, all the questions you raise boil down to the question: what is an 
 address constant expression. Apparently, the compiler chooses to consider 
 the initializer in line X to be one, while it doesn't for line Y. I cannot 
 answer the question further than what I did in my previous mail, apart 
 from the fact that line X has not cast (or, rather: a cast from one type 
 to itself), while line Y has a (reinterpret_)cast from type module to 
 incompatible type bar.
 
 Just as an aside, independent of the validity of the PR in itself: why are 
 you making it so particularly hard for the compiler to decide this? You 
 are setting module::b to &module::storage; there is simple syntax to 
 achieve this goal than teh one you use, no? :-)
 
 Cheers
   W.
 
 -------------------------------------------------------------------------
 Wolfgang Bangerth             email:            bangerth@ticam.utexas.edu
                               www: http://www.ticam.utexas.edu/~bangerth/
 
 


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

* Re: c++/9881: Incorrect address calculation for static class member
@ 2003-02-27 22:56 Peter A. Buhr
  0 siblings, 0 replies; 9+ messages in thread
From: Peter A. Buhr @ 2003-02-27 22:56 UTC (permalink / raw)
  To: nobody; +Cc: gcc-prs

The following reply was made to PR c++/9881; it has been noted by GNATS.

From: "Peter A. Buhr" <pabuhr@plg2.math.uwaterloo.ca>
To: bangerth@ticam.utexas.edu
Cc: asharji@uwaterloo.ca, gcc-bugs@gcc.gnu.org, gcc-gnats@gcc.gnu.org
Subject: Re: c++/9881: Incorrect address calculation for static class member
Date: Thu, 27 Feb 2003 17:51:18 -0500 (EST)

    > Finally, your suggestion is not even
    > a work-around, because the original problem occurred in separate compilation
    > units, so the notion of moving the constructor in this case does not apply.
 
    At which point you are out of luck in any case, since the standard does 
    not give any guarantee about the order of initialization in case there are 
    more than one translation units.
 
 I think it does. All static variables in all translation units must be
 initialized before any global constructors in any translation unit. The static
 initialization is usually done by reading constants from the .data section or by
 the linker/loader. So if I initialize a static variable in one translation
 unit, it must be initialized before a constructor is run in any another
 translation unit. I think you are referring to the order of evaluation of
 global constructors across translation units, which is undefined.
 
    May other language lawyers decide this case, regards
 
 Let me change the program slightly and see if this clarifies the situation.
 
    #include <iostream>
    
    using namespace::std;
    
    struct bar {
        double p;
    }; // bar
    
    struct module {
        static double *b;
        static double storage;
    };
    
    class foo {
      public:
        foo() {
    	// the output for both values should be the same
    	cout << &module::storage << " " << module::b << endl;
        }
    };
    
    foo f; // print output
    
    bar v;
    double *module::b = &(((bar *)(&v))->p); // LINE X
    //double *module::b = &(((bar *)(&module::storage))->p); // LINE Y
    double module::storage = 0.0;
    
    int main() {
    }
 
 If you run this with gcc3.3, the output is:
 
 @awk[5]% a.out
 0x8049a50 0x8049a48
 
 Now comment out LINE X, and uncomment LINE Y and run again getting output:
 
 @awk[6]% a.out
 0x8049a78 0
 
 Zero (0) is not an acceptable address. BUT, the only different between these 2
 lines is the chunk of storage for the object. Notice this has nothing to do
 with the constructor. One case works and one doesn't. Is this not compelling?


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

* Re: c++/9881: Incorrect address calculation for static class member
@ 2003-02-27 22:06 Wolfgang Bangerth
  0 siblings, 0 replies; 9+ messages in thread
From: Wolfgang Bangerth @ 2003-02-27 22:06 UTC (permalink / raw)
  To: nobody; +Cc: gcc-prs

The following reply was made to PR c++/9881; it has been noted by GNATS.

From: Wolfgang Bangerth <bangerth@ticam.utexas.edu>
To: "Peter A. Buhr" <pabuhr@plg2.math.uwaterloo.ca>
Cc: asharji@uwaterloo.ca, <gcc-bugs@gcc.gnu.org>, <gcc-gnats@gcc.gnu.org>
Subject: Re: c++/9881: Incorrect address calculation for static class member
Date: Thu, 27 Feb 2003 16:05:07 -0600 (CST)

 >        In this code,
 > 	 foo f; // print output
 > 
 > 	 double *module::b = &(((bar *)&module::storage)->p);
 > 	 double module::storage = 0.0;
 > 
 >        The constructor of foo is run before module::b is initialized.
 >        If you change this order, the output is as you expect.
 > 
 >        W.
 > 
 >    http://gcc.gnu.org/cgi-bin/gnatsweb.pl?cmd=view%20audit-trail&database=gcc&pr=9881
 > 
 > Your response is incorrect. First, the program generates the correct
 > result with gcc3.2. If you run the example with both gcc3.2 and gcc3.3,
 > you will see that the output is different.
 
 Just for reference: of course I did this. It is not a proof, however, 
 which one is right and which one is wrong. 
 
 
 > Hence, one can conclude that
 > either gcc3.2 or gcc3.3 is wrong. Second, when the example program is
 > run with the SUN compiler, it generates the same output as for gcc3.2,
 > indicating that the problem is probably in gcc3.3.
 
 One might guess, not conclude.
 
 
 > Third, the position of the constructor has nothing to do
 > with the assignment to a static variable. The expression to initialize the
 > static variable "module::b" *MUST* be evaluated at compiler time. All static
 > variables *MUST* be initialized before any constructor is run because a
 > constructor can refer to these variables.
 
 You are referring to 3.6.2.1, which says that POD type objects with 
 constant initializers need to be initialized before dynamic objects and 
 POD objects with non-constant initializers. Within each group, objects are 
 initialized in the order in which their definitions appear.
 
 5.19 explains what is a constant expression. 5.19.1 talks about constant 
 integral expressions, 5.19.2 about everything else, and refers to 5.19.4 
 for address constant expressions. 5.19.4 says that casts are allowed, 
 but that the value of an object shall not be accessed. I would claim that 
 this is what the expression
   ((bar *)&module::storage)->p
 is doing (note: it is not accessing p, of which we are only taking the 
 address, but it is using the result of the cast; p is not a static member 
 variable). If this claim should be correct, then the initializer would be 
 non-constant, and module::b would have to be initialized after "f", so the 
 constructor of f is run _before_ module::b is initialized.
 
 > Finally, your suggestion is not even
 > a work-around, because the original problem occurred in separate compilation
 > units, so the notion of moving the constructor in this case does not apply.
 
 At which point you are out of luck in any case, since the standard does 
 not give any guarantee about the order of initialization in case there are 
 more than one translation units.
 
 May other language lawyers decide this case, regards
   Wolfgang
 
 -------------------------------------------------------------------------
 Wolfgang Bangerth             email:            bangerth@ticam.utexas.edu
                               www: http://www.ticam.utexas.edu/~bangerth/
 
 


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

* Re: c++/9881: Incorrect address calculation for static class member
@ 2003-02-27 21:40 bangerth
  0 siblings, 0 replies; 9+ messages in thread
From: bangerth @ 2003-02-27 21:40 UTC (permalink / raw)
  To: asharji, gcc-bugs, gcc-prs, nobody, pabuhr

Synopsis: Incorrect address calculation for static class member

State-Changed-From-To: closed->open
State-Changed-By: bangerth
State-Changed-When: Thu Feb 27 21:40:33 2003
State-Changed-Why:
    Re-opened for further discussion. See my other mail for
    my view on this topic.

http://gcc.gnu.org/cgi-bin/gnatsweb.pl?cmd=view%20audit-trail&database=gcc&pr=9881


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

* Re: c++/9881: Incorrect address calculation for static class member
@ 2003-02-27 18:22 bangerth
  0 siblings, 0 replies; 9+ messages in thread
From: bangerth @ 2003-02-27 18:22 UTC (permalink / raw)
  To: asharji, gcc-bugs, gcc-prs, nobody, pabuhr

Synopsis: Incorrect address calculation for static class member

State-Changed-From-To: open->closed
State-Changed-By: bangerth
State-Changed-When: Thu Feb 27 18:22:41 2003
State-Changed-Why:
    In this code,
      foo f; // print output
    
      double *module::b = &(((bar *)&module::storage)->p);
      double module::storage = 0.0;
    
    The constructor of foo is run before module::b is initialized.
    If you change this order, the output is as you expect.
    
    W.

http://gcc.gnu.org/cgi-bin/gnatsweb.pl?cmd=view%20audit-trail&database=gcc&pr=9881


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

* c++/9881: Incorrect address calculation for static class member
@ 2003-02-27 18:06 asharji
  0 siblings, 0 replies; 9+ messages in thread
From: asharji @ 2003-02-27 18:06 UTC (permalink / raw)
  To: gcc-gnats; +Cc: pabuhr


>Number:         9881
>Category:       c++
>Synopsis:       Incorrect address calculation for static class member
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    unassigned
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Thu Feb 27 18:06:00 UTC 2003
>Closed-Date:
>Last-Modified:
>Originator:     asharji@uwaterloo.ca
>Release:        3.3 20030224 (prerelease)
>Organization:
>Environment:
System: Linux awk.math 2.4.18-bf2.4 #1 Son Apr 14 09:53:28 CEST 2002 i686 unknown
Architecture: i686

host: i686-pc-linux-gnu
build: i686-pc-linux-gnu
target: i686-pc-linux-gnu
configured with: ../gcc-20030224/configure --prefix=/u/asharji/gcc/gcc20030224/ --enable-languages=c,c++,objc --enable-threads=posix
>Description:
The calculation for:

double *module::b = &(((bar *)&module::storage)->p); 

is incorrect and should be done at compile time.

In terms of the output, the second value printed should not be  
0.
>How-To-Repeat:
g++ calcbug2.cc
./a.out

>Fix:

>Release-Note:
>Audit-Trail:
>Unformatted:
----gnatsweb-attachment----
Content-Type: text/x-c++src; name="calcbug2.cc"
Content-Transfer-Encoding: base64
Content-Disposition: attachment; filename="calcbug2.cc"

I2luY2x1ZGUgPGlvc3RyZWFtPgoKdXNpbmcgbmFtZXNwYWNlOjpzdGQ7CgpzdHJ1Y3QgYmFyIHsK
ICAgIGRvdWJsZSBwOwp9OyAvLyBiYXIKCnN0cnVjdCBtb2R1bGUgewogICAgc3RhdGljIGRvdWJs
ZSAqYjsKICAgIHN0YXRpYyBkb3VibGUgc3RvcmFnZTsKfTsKCmNsYXNzIGZvbyB7CiAgcHVibGlj
OgogICAgZm9vKCkgewoJLy8gdGhlIG91dHB1dCBmb3IgYm90aCB2YWx1ZXMgc2hvdWxkIGJlIHRo
ZSBzYW1lCgljb3V0IDw8ICZtb2R1bGU6OnN0b3JhZ2UgPDwgIiAiIDw8IG1vZHVsZTo6YiA8PCBl
bmRsOwogICAgfQp9OwoKZm9vIGY7IC8vIHByaW50IG91dHB1dAoKZG91YmxlICptb2R1bGU6OmIg
PSAmKCgoYmFyICopJm1vZHVsZTo6c3RvcmFnZSktPnApOyAvLyBzaG91bGQgYmUgYSBjb21waWxl
LXRpbWUgY2FsY3VsYXRpb24KZG91YmxlIG1vZHVsZTo6c3RvcmFnZSA9IDAuMDsKCmludCBtYWlu
KCkgewp9Cg==


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

end of thread, other threads:[~2003-03-02 22:16 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2003-02-27 21:46 c++/9881: Incorrect address calculation for static class member Peter A. Buhr
  -- strict thread matches above, loose matches on Subject: below --
2003-03-02 22:16 Wolfgang Bangerth
2003-02-28 13:56 Peter A. Buhr
2003-02-27 23:16 Wolfgang Bangerth
2003-02-27 22:56 Peter A. Buhr
2003-02-27 22:06 Wolfgang Bangerth
2003-02-27 21:40 bangerth
2003-02-27 18:22 bangerth
2003-02-27 18:06 asharji

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