RAD Studio |  |

Stricter C++ Compiler: Binding of References and Qualifiers
Reconcile Error Dialog: Solving Problems | See Also
Collapse All

There are many constructs that now generate error messages from the CodeGear C++ compiler included with C++Builder 2007 and newer releases. The rules governing this behavior are described in section 8.5.3 of the 2003 C++ ANSI standard.

The rules can be divided into the following categories (with the compiler switch that overrides this behavior):

- Binding a non-const lvalue to to non-const reference. (Use the compiler switch -Vbr to allow this.)
- Binding a temporary to a non-const reference. (Use the compiler switch -Vbr to allow this.)
- Binding of const or volatile objects to non-const or non-volatile methods repectively. (Use the compiler switch -Vbn to allow this.)

Previous versions of the Borland C++ compilers allowed various forms of binding to non-const reference parameters. In the following example, for instance, one was allowed to simply cast the psize parameter:
Copy Code

    int takesLongRef(long& l);

      int takesUnsignedPtr(unsigned long* psize) {

         return takesLongRef((long)*psize);
      }

With C++Builder2007, the above code generates these errors:

Copy Code

    Error E2357 test.cpp 3: Reference initialized with 'long', needs lvalue of type 'long' in function takesUnsignedPtr(unsigned long *)

Copy Code

    Error E2342 test.cpp 3: Type mismatch in parameter 'l' (wanted 'long &', got 'long') in function takesUnsignedPtr(unsigned long *)

To remedy this, you can cast psize before dereferencing, as in:

Copy Code

    int takesLongRef(long& l);
    int takesUnsignedPtr(unsigned long* psize) {     return takesLongRef(*reinterpret_cast <long*>(psize));   }

Be aware of cases that involve temporaries in unobvious ways. For example, some binary operators imply a temporary:

Copy Code

    enum { zero, one, two } num;
    num |= two; // Not allowed
    num = num | two; // OK

Another case that involves temporaries in an unobvious way is the return value of a property. The following example illustrates code that compiled with previous versions of the compiler:

Copy Code

    #include <vcl.h>

    class TTest {
       WideString FData ;
    public:
       __property WideString Data = {read = FData };
    };

    void Func(WideString& wref);

    void test() {
       TTest t;
       Func(t.Data);
    }

With C++Builder 2007, the above generates two errors:

Copy Code

    Error E2357 test.cpp 14: Reference initialized with 'const WideString', needs lvalue of type 'WideString' in function test()

Copy Code

    Error E2342 test.cpp 14: Type mismatch in parameter 'wref' (wanted 'WideString &', got 'WideString') in function test()

You can fix this by changing the reference to a const reference, as in:

void Func(const WideString& wref);

Here is an example of trying to bind a const object to a non-const method:

Copy Code

    struct X {
       void foo();
    };
    const X x;
    x.foo(); //error

Reconcile Error Dialog: Solving Problems

The temporaries and references issue referred to above is encountered in code generated by previous versions of the Reconcile Error Dialog Wizard.

To remedy this, look for the VarToAnsiStr method:

Copy Code

    AnsiString VarToAnsiStr (Variant &V TFieldType DataType)

and change it to take a const Variant&, as in:

Copy Code

    AnsiString VarToAnsiStr (const Variant &V, TFieldType DataType)

See Also

Stricter C++ Compiler (C++Builder 2007)

String Literals Are Now Constants

Template Changes

Function Overload Resolution

Initialization and Conversion

Copyright(C) 2009 Embarcadero Technologies, Inc. All Rights Reserved.
What do you think about this topic? Send feedback!