Incompatible behavior -O0, -O3, std::cout

2005-11-18 Thread Pankaj Gupta

Hello Everyone

I noticed some thing strange recently. This code (under g++ (GCC) 3.2.3 
20030502 (Red Hat Linux 3.2.3-53)), provides this output with -O0 flag:

-f2() called
-f1() called-
12

And with -O3 flag:
-f1() called-
-f2() called
12

Here's the code:

#include 
#include 


int f1() {
  fprintf(stderr, "-f1() called-\n");
  return 1;
}


int f2() {
  fprintf(stderr, "-f2() called\n");
  return 2;
}

int main(int argc, char **argv) {
 std::cout << f1() << f2() << std::endl;
}


I'm pretty sure that I am depending on an undefined behavior here, but 
maybe you guys would want to have a deeper look at this.



Also, if this is not very off-topic, could some one please tell me whether 
the << operators for std::ostream are members of the class, or are global 
functions (operators).


I think, if are global, it would be same as depending upon the order of 
evaluation of arguments to a function (which would be wrong according to 
the C++ standard), but if they were members of the stream classes, then it 
would evaluate to a().b().c().d() and we should expect f1() to be called 
before f2(). - Is that correct?



Thanks and Best Regards
Pankaj


--



--
 Pankaj Gupta
 Infrastructure Team   -   Tower Research Capital

 Phone: 212-219-6012 [Work]
551-358-0684 [Cell]

 Mail:  [EMAIL PROTECTED]
--





Re: Incompatible behavior -O0, -O3, std::cout

2005-11-18 Thread Pankaj Gupta

Thanks Andrew. That answers it.

Pankaj


On Fri, 18 Nov 2005, Andrew Pinski wrote:



Hello Everyone

I noticed some thing strange recently. This code (under g++ (GCC) 3.2.3
20030502 (Red Hat Linux 3.2.3-53)), provides this output with -O0 flag:
int main(int argc, char **argv) {
  std::cout << f1() << f2() << std::endl;
}


I'm pretty sure that I am depending on an undefined behavior here, but
maybe you guys would want to have a deeper look at this.



Yes are you dependening on undefined behavior.   Since there is no sequence 
point
between the calls to f1() and f2(), then they can be evaluated in either order.


I think, if are global, it would be same as depending upon the order of
evaluation of arguments to a function (which would be wrong according to
the C++ standard), but if they were members of the stream classes, then it
would evaluate to a().b().c().d() and we should expect f1() to be called
before f2(). - Is that correct?


No because the above is equvliant to the following pesdu C code:

operator <<(operator << (operator << (std::cout, f1()), f2()), std::endl)

and the order evaluatation of expressions inside a function call is undefined.

Thanks,
Andrew Pinski




--



----------
 Pankaj Gupta
 Infrastructure Team   -   Tower Research Capital

 Phone: 212-219-6012 [Work]
551-358-0684 [Cell]

 Mail:  [EMAIL PROTECTED]
--




Accessing const object during constructor without this pointer

2005-12-05 Thread Pankaj Gupta

Hi

I have a question. Consider this code:

#include 

void global_init();

class A {
public:
  int i;
  A() : i(10) {
global_init();
  }
};

const A obj;

void global_init() {
  std::cout << "obj.i = " << obj.i << std::endl;
}

int main() {
  return EXIT_SUCCESS;
}



Here, global_init() is accessing a subobject of a const object, while its 
being constructed. I think the standard says that, if the access in not 
being made through the constructor's "this" (directly or indirectly), the 
value of the const object or any subobject is unspecified.


But when I compile using g++, I don't get any warnings about it.

Any idea if this should be giving warnings or not.


Best Regards
Pankaj



--

Pankaj Gupta

Infrastructure Team
Tower Research Capital

[EMAIL PROTECTED]  [Work]
[EMAIL PROTECTED]   [Personal]