0

Can anyone tell me what happens here when passing to g in the main, is it static_cast?

int  & g (int&x){x++ ; return x ; } 
int main()
{

   const int a=5 ; 
   cout<<g((int&)a)<<endl; 
}

I am sure that no copy is made, since the code above is similar to the one below :

class A
{
public:
    A()
    {
        cout << "calling DEFAULT constructor\n\n";
    }
    A(A& Other)
    {
        cout << "Calling COPY constructor\n\n";
    }
    ~A()
    {
        cout << "Calling DESTRUCTOR\n\n";
    }
};

A& g(A& x)
{
    cout << "Inside g(A& x) \n\n";
    return x;
}

void main()
{
    const A a;
    g(const_cast<A&>(a));
}*/

Thanks in advance :)

Tamer Shlash
  • 9,314
  • 5
  • 44
  • 82
  • 3
    [The return type of `main` is always `int`](http://stackoverflow.com/questions/4207134/what-is-the-proper-declaration-of-main/4207223#4207223). – James McNellis Jan 30 '11 at 21:42
  • @James : is what you say a standard? and is what I wrote non-standard? I'm waiting for your answer, and thanks alot :) – Tamer Shlash Jan 30 '11 at 21:44
  • Just a last Question, what is the cast that applies if we make "a" a variable (not const)? thanks to anyone who answers :) – Tamer Shlash Jan 30 '11 at 22:20
  • what is the reason for postfix `++` here? `int & g (int&x){x++ ; return x ; }` why not `int & g (int&x){return ++x ; }`? – Andriy Tylychko Jan 31 '11 at 00:06

3 Answers3

8

static_cast cannot remove constness. This is a const_cast.

At runtime, this code (the first example) yields undefined behavior because you modify a const object.

James McNellis
  • 348,265
  • 75
  • 913
  • 977
  • Oops, I missed and wrote static_cast instead of const_cast, thanks alot for answering. – Tamer Shlash Jan 30 '11 at 21:34
  • Is the undefined behavior definitely restricted to runtime? Or could a confirming compiler detect the violation and reboot the computer at compile time or something? – fredoverflow Jan 30 '11 at 21:52
  • 2
    @Fred: My understanding is that the expression only yields undefined behavior when it is evaluated. So, I think the undefined behavior is restricted to runtime since there is no guarantee that the expression will be evaluated (e.g., another translation unit might have some static initialization that calls `std::exit()`, and since that would occur before `main()` is entered, the expression won't be evaluated.) – James McNellis Jan 30 '11 at 21:55
  • @Fred AFAIK undefined behaviour never excuses the compiler for crashing, launching zee missiles etc. **during compilation**. UB is a runtime phenomenon. The compiler could, though, detect the violation and emit a warning like "guaranteed to invoke undefined behaviour" (or "likely", etc., as appropriate), which the user may treat as an error. – Karl Knechtel Jan 30 '11 at 22:03
  • Just a last Question, what is the cast that applies if we make "a" a variable (not const)? thanks to anyone who answers :) – Tamer Shlash Jan 30 '11 at 22:24
  • I don't think the example with `A` has UB. – GManNickG Jan 30 '11 at 22:46
  • @Karl: That's not correct. This program exhibits undefined behavior: `void main() { }`. It would be perfectly acceptable for a compiler to crash or otherwise "misbehave" given that program. – James McNellis Jan 30 '11 at 22:54
  • 1
    @GMan: No, the second example does not exhibit undefined behavior. The first example certainly does. (I read the question as being specifically about the first example; I'll clarify, thanks!) – James McNellis Jan 30 '11 at 22:55
  • @Mr.TAMER: It would be a no-op static cast. – James McNellis Jan 30 '11 at 22:56
1

A C-style cast is a vicious thing -- it will do everything that a reinterpret_cast<> or a const_cast<> will do. It's one of those "the power of a chainsaw with the ease-of-use of a chainsaw" things that C is rightly infamous for.

Using the C++-style casts will show that you need to do a const_cast<>, and then you should ask yourself why and find a better way to do it.

AAT
  • 3,286
  • 1
  • 22
  • 26
0

For int, there's no code needed to just pass the reference in. Your cast lets it compile.

Lou Franco
  • 87,846
  • 14
  • 132
  • 192
  • I know, but what cast does the compiler implicitly do? – Tamer Shlash Jan 30 '11 at 21:35
  • 1
    It's certainly not reinterpret cast, as the bits of int are not the same as a reference. It's also certainly not dynamic, because int isn't a class with virtual functions, and int& is not a superclass of int. It can't be static, because you can't change constness. So, if it's anything, it's const -- but nothing says an old-style cast has to do what a new style one does. – Lou Franco Jan 30 '11 at 21:45
  • 2
    Actually, the C-style cast is specified in terms of static, const, and reinterpret cast, so it always performs some combination of those three (though, some of the behavior is slightly different, e.g. a C-style cast does not check base class accessibility before performing a static cast, so you can cast to a private base using a C-style cast but you can't using a static cast). – James McNellis Jan 30 '11 at 21:49
  • I think we're saying the same thing -- I say it's not definitely one of the new style, and you say it could be a combo or different behavior. – Lou Franco Jan 30 '11 at 22:17