Given class COtherClass having methods class COtherClass { ... inline COtherClass(unsigned int uiParam1, const char *pszParam2, const char *pszParam3, unsigned long ulParam4, const char *pszParam5) {...} ~COtherClass(); COtherClass &Method1(); COtherClass &Method2(unsigned long long &ullParam); COtherClass &operator ()(const char *pszParam1, const void *pvParam2); COtherClass &operator ()(const char *pszParam1, unsigned long long ullParam2) { ... } }; For code struct CHostClass { public: unsigned long long m_ullProblemField; const void *m_pvPointerField; const char *m_szSzField; ~CHostClass() { COtherClass(5, m_szSzField, NULL, 0, "ImmString1").Method1().Method2(m_ullProblemField)("ImmString2", m_pvPointerField)("ImmString3", m_ullProblemField); } }; GCC generated the following assembler text (debug build) mov 0x8(%ebp),%eax // CHostClass::this pushl 0x4(%eax) // HI(CHostClass::m_ullProblemField) pushl (%eax) // LO(CHostClass::m_ullProblemField) push $0x81f10f9 // "ImmString3" sub $0x8,%esp mov 0x8(%ebp),%eax // CHostClass::this pushl 0x8(%eax) // CHostClass::m_pvPointerField push $0x81f0e3a // "ImmString2" sub $0xc,%esp pushl 0x8(%ebp) // CHostClass::this <=> offset CHostClass::m_ullProblemField sub $0xc,%esp push $0x81f1104 // "ImmString1" push $0x0 // 0 push $0x0 // NULL mov 0x8(%ebp),%eax // CHostClass::this pushl 0xc(%eax) // CHostClass::m_szSzField push $0x5 // 5 lea 0xfffff4e8(%ebp),%eax // storage for COtherClass instance push %eax call 0x804e61c // COtherClass::COtherClass constructor add $0x24,%esp // 6*4 params + 12 reserve made with "sub $0xc,%esp" lea 0xfffff4e8(%ebp),%eax // instance of COtherClass push %eax call 0x818e68e // COtherClass::Method1 add $0x4,%esp // 1 param push %eax // instance of COtherClass call 0x8190384 // COtherClass::Method2 add $0x14,%esp // 2*4 params + 12 reserve made with "sub $0xc,%esp" push %eax // instance of COtherClass call 0x818e85c // COtherClass::operator()(const char *, const void *) add $0x14,%esp // 3*4 params + 8 reserve made with "sub $0x8,%esp" push %eax // instance of COtherClass call 0x804f322 // COtherClass::operator()(const char *, unsigned long long) add $0x10,%esp // 2*4 + 1*8 params sub $0xc,%esp lea 0xfffff4e8(%ebp),%eax // instance of COtherClass push %eax call 0x818e610 // COtherClass::~COtherClass add $0x10,%esp // 1*4 params + 12 reserve made with "sub $0xc,%esp" The problem is that the value of m_ullProblemField is pushed to stack at the very beginning of code while it is modified later during invocation of COtherClass::Method2. COtherClass::operator (const char *, unsigned long long) should receive modified value of field but it receives initial one.
The evaluation order of function arguments is not specified. If you depend on side effects to be carried out at a specific point you must make sure there is a sequence point at the appropriate place.
(In reply to comment #1) > The evaluation order of function arguments is not specified. If you depend on > side effects to be carried out at a specific point you must make sure there is > a sequence point at the appropriate place. These are not the arguments of a single function. Given example is the sequence of method invocations for a class instance. Modification of lvalue occurs in 2nd method invocation and it is supposed to be passed to 4th method invocation.
Do you have a testcase that actually compiles?
Created attachment 12509 [details] Compilable testcase
(In reply to comment #0) > COtherClass(5, m_szSzField, NULL, 0, > "ImmString1").Method1().Method2(m_ullProblemField)("ImmString2", > m_pvPointerField)("ImmString3", m_ullProblemField); > [...] > The problem is that the value of m_ullProblemField is pushed to stack at the > very beginning of code while it is modified later during invocation of > COtherClass::Method2. COtherClass::operator (const char *, unsigned long long) > should receive modified value of field but it receives initial one. No. The order of evaluation of your sequence of function calls is unspecified. There is no sequence point within your chain of calls, and therefore the compiler is free to select whatever order for evaluating the arguments of all these calls. W.