Re: missing optimization - don't compute return value not used?
In version 1, the return type is "a_t", so a class construction is required there (the caller will then destruct the returned object). Construction and destruction can have side effects, so the compiler would not drop them. For the following code, template inline a_t& append (a_t & a, b_t const& b) { a.insert (a.end(), b.begin(), b.end()); return a; } it does not require a construction, and would be as fast as version 2. On 9/26/07, Neal Becker <[EMAIL PROTECTED]> wrote: > gcc version 4.1.2 20070502 (Red Hat 4.1.2-12) > I noticed the following code > > === version 1: > template > inline a_t append (a_t & a, b_t const& b) { > a.insert (a.end(), b.begin(), b.end()); > return a; > } > > === version 2: > template > inline void append (a_t & a, b_t const& b) { > a.insert (a.end(), b.begin(), b.end()); > } > > When instantiated for a_t, b_t std::list. When called by code that _did > not use the return value_, I had assumed that since the returned value is > not used, the 2 versions would be equivalent. Instead, (compiling > with -O3), version 2 runs very fast, but version 1 is extremely slow. Is > it really necessary to construct the returned value even when it is seen > that it is not used? > >
Re: missing optimization - don't compute return value not used?
Right, page 211 of the C++ standard (2003) explains when copy-ctor and dtor are allowed to be optimized away. But the two circumstances are both like this: A is constructed; A is copy-constructed to B; A is destructed Here A is a temporary object in some sense, and the standard allows for directly constructing B. However, Neal expected the compiler to optimize "A is constructed; A is destructed" away. I find nowhere in the standard that allows this. ps, Did you forget to put [EMAIL PROTECTED] in the cc list? On 9/26/07, Michael Veksler <[EMAIL PROTECTED]> wrote: > But, according to the C++ standard, the compiler is allowed to optimize > copy construction away. GCC does that in many occasions . For example try: > | > #include > using namespace std; > struct T { > T() { } > T(const T&) { cout << "!!! copy ctor !!! \n"; } > }; > T f() { T t; return t;} > int main() > { > cout << "No copy\n"; > T no_copy= f(); > > cout << "Expecting copy\n"; > T copy= no_copy; > } > |
Re: Is this a bug?
It's not a bug. It conforms the C standard. C, unlike C++, distinguishes functions ONLY by name, not by arguments. C allows calling functions that are not declared by assuming they return int. So GCC would assume that the prototype of "func" to be "int func()" when compiling "main.c", and can generate a call to "func", although it's defined in another file with a different prototype. When the prototypes are different, the behavior is undefined. (Yes, this would be a link error in C++. But for C, it's the programmer's responsibility to make sure arguments and return values are passed correctly if you call undeclared functions. Therefore, it is always encouraged that every function be declared before called, even in C code.) On 9/29/07, Zhang Xiaoping <[EMAIL PROTECTED]> wrote: > two c files: main.c and func.c, excute the command like this: > > gcc main.c func.c -Wall -ansi -pedantic > > there are two warnings, and is can generate binary file and the file > can be excuted. > > //main.c > > int main() > { > int a; > a = func(); > printf("%d\n", a); > return a; > } > > //func.c > float func(int a, int b) > { > return (float)(a + b); > } > > I assume it's a bug: func in main funcion is different from the > function in func.c > > My gcc version is gcc 3.2.2. > > May be not this version, i have forgotten. >