Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C++ > why static_cast needed here to produce proper output

Reply
Thread Tools

why static_cast needed here to produce proper output

 
 
nin234ATIyahoo.com
Guest
Posts: n/a
 
      03-16-2005
Hi all
I have a logger class and facing the following issue

enum eErrLvl
{
eLOG_DEBUG_5 = 1,
eLOG_DEBUG_4,
eLOG_DEBUG_3,
eLOG_DEBUG_2,
eLOG_DEBUG_1,
eLOG_INFO,
eLOG_WARNING,
eLOG_ERROR,
eLOG_FATAL
};


std:stream&
operator << (std:stream& os, eErrLvl& eLvl)
{
switch (eLvl)
{
case eLOG_DEBUG_5:
os << "Debug_5\t: ";
break;
case eLOG_DEBUG_4:
os << "Debug_4\t: ";
break;
case eLOG_DEBUG_3:
os << "Debug_3\t: ";
break;
case eLOG_DEBUG_2:
os << "Debug_2\t: ";
break;
case eLOG_DEBUG_1:
os << "Debug_1\t: ";
break;
case eLOG_INFO:
os << "Info\t: ";
break;
case eLOG_WARNING:
os << "Warn\t: ";
break;
case eLOG_ERROR:
os << "Error\t: ";
break;
case eLOG_FATAL:
os << "Fatal\t: ";
break;
}
return os;
}

class srvLog
{
static int volatile nLglvl;

//volatile keyword is a hint to compiler an object may change the
value
//in a way not specified by the language and aggressive
optimizations
//must be avoided

eErrLvl nSeverity;
public:
friend std:stream& operator << (std:stream& , const
srvLog&);

};
std:stream& operator << (std:stream& os, const srvLog& oLog)
{
os << "initial msg " << static_cast<eErrLvl>(oLog.nSeverity);
return os;
}
My problem is with this statement
os << "initial msg " << static_cast<eErrLvl>(oLog.nSeverity);

Only when I use the static_cast does it invoke the operator (<<) for
the enum. Otherwise it just prints the integer value corresponding to
the enum
ie if I use
os << "initial msg " << (oLog.nSeverity);

Ninan

 
Reply With Quote
 
 
 
 
Victor Bazarov
Guest
Posts: n/a
 
      03-16-2005
nin234ATIyahoo.com wrote:
> [...]
> My problem is with this statement
> os << "initial msg " << static_cast<eErrLvl>(oLog.nSeverity);
>
> Only when I use the static_cast does it invoke the operator (<<) for
> the enum. Otherwise it just prints the integer value corresponding to
> the enum
> ie if I use
> os << "initial msg " << (oLog.nSeverity);


The compiler promotes 'nSeverity' to 'int' and finds that there is
operator << among the members of 'ostream', and uses it to output
the value. If you static_cast it, the compiler is prevented from
promoting the enum to int. IIRC.

V
 
Reply With Quote
 
 
 
 
nin234ATIyahoo.com
Guest
Posts: n/a
 
      03-16-2005
actually ; that precisly is my question. Why does the compiler promote
the enum to int, when there is already an operator defined for it

 
Reply With Quote
 
Victor Bazarov
Guest
Posts: n/a
 
      03-16-2005
nin234ATIyahoo.com wrote:
> actually ; that precisly is my question. Why does the compiler promote
> the enum to int, when there is already an operator defined for it


Hard to say, a bug in the compiler, maybe?
 
Reply With Quote
 
=?iso-8859-1?Q?Ali_=C7ehreli?=
Guest
Posts: n/a
 
      03-16-2005
"nin234ATIyahoo.com" <(E-Mail Removed)> wrote in message
news:(E-Mail Removed) oups.com...
> Hi all
> I have a logger class and facing the following issue
>
> enum eErrLvl
> {
> eLOG_DEBUG_5 = 1,
> eLOG_DEBUG_4,
> eLOG_DEBUG_3,
> eLOG_DEBUG_2,
> eLOG_DEBUG_1,
> eLOG_INFO,
> eLOG_WARNING,
> eLOG_ERROR,
> eLOG_FATAL
> };
>
>
> std:stream&
> operator << (std:stream& os, eErrLvl& eLvl)
> {


Change the type of eLvl to either

eErrLvl const &

or

eErrLvl

of which, probably the latter is better for an enum.

> switch (eLvl)
> {
> case eLOG_DEBUG_5:


[...]

> std:stream& operator << (std:stream& os, const srvLog& oLog)
> {
> os << "initial msg " << static_cast<eErrLvl>(oLog.nSeverity);


oLog is const is this context, so is oLog.nSeverity. The compiler cannot
dispatch operator<< that takes a non-const eErrLvl (as you wrote.)

The change above should fix the problem.

> return os;
> }
> My problem is with this statement
> os << "initial msg " << static_cast<eErrLvl>(oLog.nSeverity);
>
> Only when I use the static_cast does it invoke the operator (<<) for
> the enum. Otherwise it just prints the integer value corresponding to
> the enum
> ie if I use
> os << "initial msg " << (oLog.nSeverity);


Ali

 
Reply With Quote
 
Andrey Tarasevich
Guest
Posts: n/a
 
      03-16-2005
nin234ATIyahoo.com wrote:

> actually ; that precisly is my question. Why does the compiler promote
> the enum to int, when there is already an operator defined for it
>


You 'operator <<' for 'eErrLvl' type is declared as

std:stream& operator << (std:stream& os, eErrLvl& eLvl)

Note that it takes its second argument by non-constant reference.

At the same time 'operator <<' for 'srvLog' takes its second operand by
constant reference

std:stream& operator << (std:stream& os, const srvLog& oLog)

Now, inside the latter operator you are trying to do the following

os << "initial msg " << oLog.nSeverity;

But compiler cannot call the former operator in this case for an obvious
reason: the "constness" of 'oLog' propagates to 'oLog.nSeverity',
meaning that 'oLog.nSeverity' is considered to be a const-qualified
value. Compiler cannot bind a non-constant parameter to a constant
argument in the 'operator <<' call.

Instead, it has to seek a workaround solution, which presents itself in
form of a standard 'enum -> int' conversion followed by a call to
'operator <<' for 'int's. The compiler is behaving correctly in this case.

Strictly speaking, your 'static_cast' is not supposed to change
anything. The result of that cast is not an lvalue and non-constant
reference still cannot be bound to it. I don't understand why you
compiler suddenly decides to choose your operator after the cast. _This_
looks like a bug in the compiler.

If you want the compiler to use your 'operator <<' for 'eErrLvl', you
have to declare it as either

std:stream& operator << (std:stream& os, eErrLvl eLvl)

or

std:stream& operator << (std:stream& os, const eErrLvl& eLvl)

I'd stick with the first variant. There absolutely no reason to use a
reference here, especially a non-constant one. How did you come to an
idea to pass the 'eErrLvl' value as 'eErrLvl&' reference in the first place?

--
Best regards,
Andrey Tarasevich
 
Reply With Quote
 
nin234ATIyahoo.com
Guest
Posts: n/a
 
      03-16-2005
thanks this works; I am using g++ on linux btw (gcc 3.2.3)

 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
findcontrol("PlaceHolderPrice") why why why why why why why why why why why Mr. SweatyFinger ASP .Net 2 12-02-2006 03:46 PM
can java produce .exe? if it can produce jar,how do you do? aungkopyay@gmail.com Java 5 10-27-2006 02:07 AM
Is static_cast<int>(static_cast<double>(a)) == a? Bo Peng C++ 11 10-20-2006 12:59 PM
Wrong usage of static_cast: is output undefined or predicted? Alex Vinokur C++ 1 09-27-2004 05:23 AM
Would a static_cast be better style here? Steven T. Hatton C++ 26 04-19-2004 02:12 AM



Advertisments