------- Comment #20 from jorg dot brown at gmail dot com  2008-06-11 00:07 
-------
Interesting, but I'm not sure this can legally be done.

Consider:

struct POD {
  int x;
  int y;
};

struct nonPOD {
  int x;
  int y;
  nonPOD(int xx, int yy) : x(xx), y(yy) { }
};

I, for one, would love to see "nonPOD foo(1, 2);" be treated as efficiently as
"POD foo = {1, 2};", and I would argue that the case that should be optimized
is when the arguments to the constructor are known at compile time, the body of
the constructor is completely empty, and all the member variables are POD.

However let us consider this example program, starting with the definitions
above and the requisite header files and then:

extern const POD    pod;
extern const nonPOD nonpod;

std::string podStr(pod.x, '*');
std::string nonpodStr(nonpod.x, '*');

const POD pod = {1, 2};
const nonPOD nonpod(1, 2);

int main(int argc, char *argv[]) {
  std::cout << "podStr = '" << podStr << "'\n";
  std::cout << "nonpodStr = '" << nonpodStr << "'\n";
  return 0;
}

Now, the order of construction is well-defined, and that is why the program
produces:

podStr = '*'
nonpodStr = ''

That is, the nonPOD is still zero-filled when the constructor for nonpodStr
runs, so nonpodStr ends up empty.

I believe that if you change nonPOD so that it sits in .rodata, then it has to
be initialized prior to nonpodStr.  This changes the behavior of this perfectly
valid program.  No?

(Just for the record, I would whole-heartedly endorse a change to the C++
standard to allow this optimization)


-- 


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

Reply via email to