C++Talk.NET Forum Index C++Talk.NET
C++ language newsgroups
 
Archives   FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

Compiler error or? Microsoft VC++ v6.0
Goto page 1, 2  Next
 
Post new topic   Reply to topic    C++Talk.NET Forum Index -> C++ Language (Moderated)
View previous topic :: View next topic  
Author Message
Torstein Hansen
Guest





PostPosted: Wed Feb 18, 2004 12:29 pm    Post subject: Compiler error or? Microsoft VC++ v6.0 Reply with quote



The following code gives us a little headache.

Calls to foobar with parameter u0 (set to 0) compiles without warnings,
but using parameter u1 (equal to 1) gives a compiler error "Cannot
convert from const unsigned long to const class foo &"

I really can't see why it would make any difference what numerical value
is used.

Anyone care to explain? Is it me or the compiler that is half-blind?

<code>

class foo
{
public:
foo();
foo(const foo &f);
foo(char* pc);
};

class bar
{
public:
bar();

bool foobar(const foo& rf);
};

void main()
{
bar b;
const unsigned long u0 = 0;
const unsigned long u1 = 1;

b.foobar(u0);
b.foobar(u1);
}

</code>

Torstein Hansen
(Remove "RemoveThis" to answer by mail)



[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
Back to top
Ben Hutchings
Guest





PostPosted: Thu Feb 19, 2004 10:25 am    Post subject: Re: Compiler error or? Microsoft VC++ v6.0 Reply with quote



Torstein Hansen wrote:
Quote:
The following code gives us a little headache.

Calls to foobar with parameter u0 (set to 0) compiles without warnings,
but using parameter u1 (equal to 1) gives a compiler error "Cannot
convert from const unsigned long to const class foo &"

I really can't see why it would make any difference what numerical value
is used.

Anyone care to explain? Is it me or the compiler that is half-blind?

code

class foo
{
public:
foo();
foo(const foo &f);
foo(char* pc);
};

class bar
{
public:
bar();

bool foobar(const foo& rf);
};
snip


It's a bizarre result of the definition of integer constant
expression. const variables of integer type are integer constant
expressions. Any integer constant expression that evaluates to 0 can
be implicitly converted to a pointer type, resulting in a null pointer
of that type. So u0 is converted to foo((char *)0) but u1 cannot
be converted to foo.

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
Thomas Mang
Guest





PostPosted: Thu Feb 19, 2004 10:29 am    Post subject: Re: Compiler error or? Microsoft VC++ v6.0 Reply with quote





Torstein Hansen schrieb:

Quote:
The following code gives us a little headache.

Calls to foobar with parameter u0 (set to 0) compiles without warnings,
but using parameter u1 (equal to 1) gives a compiler error "Cannot
convert from const unsigned long to const class foo &"

I really can't see why it would make any difference what numerical value
is used.

Anyone care to explain? Is it me or the compiler that is half-blind?

code

class foo
{
public:
foo();
foo(const foo &f);
foo(char* pc);

These 2 constructors can both act as conversion functions.
This will play a role later.

Maybe they should better be declared 'explicit' ?

Quote:
};

class bar
{
public:
bar();

bool foobar(const foo& rf);
};

void main()

Invalid C++. You have to return an int.


Quote:

{
bar b;
const unsigned long u0 = 0;
const unsigned long u1 = 1;

b.foobar(u0);

This call works because
-) u0 is declared as a *constant* with the value zero
-) there is an implicit conversion from the zero constant to a pointer value

-) one of the foo constructors takes a pointer value as argument and is not
'explicit'. (e.g. it can act as conversion function).

The compiler calls the
foo(char*);
constructor of foo, and passes in the null pointer.


You could make the code fail by doing one of this:

-) remove the const from u0.
-) declare the foo(char*) constructor as 'explicit'.

Quote:

b.foobar(u1);

This code cannot work, because there is no implicit conversion from the
constant '1' to a pointer value, so this line triggers a compilation error.
All unsigned long constants except '0' share the same fate.


Quote:

}

regards,

Thomas

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
Benjamin Golinvaux
Guest





PostPosted: Thu Feb 19, 2004 10:34 am    Post subject: Re: Compiler error or? Microsoft VC++ v6.0 Reply with quote

hi

section C.6.2.3 of "the C++ programming language" says

"A constant expression that evaluates to 0 can be implicitly converted
to any pointer or pointer to member type".

This is why
somePointer = NULL
with
#define NULL 0
doesn't require a cast

very handy...

Benjamin-


"Torstein Hansen" <torsteinRemoveThis (AT) hansen (DOT) as> wrote

Quote:
The following code gives us a little headache.

Calls to foobar with parameter u0 (set to 0) compiles without warnings,
but using parameter u1 (equal to 1) gives a compiler error "Cannot
convert from const unsigned long to const class foo &"

I really can't see why it would make any difference what numerical value
is used.

Anyone care to explain? Is it me or the compiler that is half-blind?

code

class foo
{
public:
foo();
foo(const foo &f);
foo(char* pc);
};

class bar
{
public:
bar();

bool foobar(const foo& rf);
};

void main()
{
bar b;
const unsigned long u0 = 0;
const unsigned long u1 = 1;

b.foobar(u0);
b.foobar(u1);
}

/code

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
Francis Glassborow
Guest





PostPosted: Thu Feb 19, 2004 1:31 pm    Post subject: Re: Compiler error or? Microsoft VC++ v6.0 Reply with quote

In message <oZuYb.460$72.179822080 (AT) news (DOT) telia.no>, Torstein Hansen
<torsteinRemoveThis (AT) hansen (DOT) as> writes
Quote:
The following code gives us a little headache.

Calls to foobar with parameter u0 (set to 0) compiles without warnings,
but using parameter u1 (equal to 1) gives a compiler error "Cannot
convert from const unsigned long to const class foo &"

I really can't see why it would make any difference what numerical value
is used.
True, with the solitary exception of a compile time zero value which can

be a null pointer constant. And that is your problem here.
Quote:

Anyone care to explain? Is it me or the compiler that is half-blind?

code

class foo
{
public:
foo();
foo(const foo &f);
foo(char* pc);

This constructs a foo given a pointer to a char. 0 is such a pointer if
it can be interpreted as a null pointer constant. All other integer
values require a cast to convert them (in an implementation defined way)
into a pointer.
Quote:
};

--
Francis Glassborow ACCU
Author of 'You Can Do It!' see http://www.spellen.org/youcandoit
For project ideas and contributions: http://www.spellen.org/youcandoit/projects


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
Jonathan Turkanis
Guest





PostPosted: Thu Feb 19, 2004 1:36 pm    Post subject: Re: Compiler error or? Microsoft VC++ v6.0 Reply with quote


"Torstein Hansen" <torsteinRemoveThis (AT) hansen (DOT) as> wrote

Quote:
The following code gives us a little headache.

Calls to foobar with parameter u0 (set to 0) compiles without
warnings,
but using parameter u1 (equal to 1) gives a compiler error "Cannot
convert from const unsigned long to const class foo &"

I really can't see why it would make any difference what numerical
value
is used.

An intergral constant expression rvalue that evaluates to zero can be
converted to any pointer type. (4.10)

Therefore you can write

char* c = 701 * 1429 - 1001729;

but not

char* c = 661 * 1381- 912840;

Jonathan



[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
Chris Underwood
Guest





PostPosted: Thu Feb 19, 2004 2:10 pm    Post subject: Re: Compiler error or? Microsoft VC++ v6.0 Reply with quote

I'm just guessing here, but for some reason 0 is a valid pointer
value, but other integers are not.

int main(){

char *a = 0; // This works
int *x = 0; // This works

char *b = 1; // cannot convert blah blah
int *y = 1; // cannot convert blah blah

return 0;
}

Looking a bit further I found
#ifndef NULL
#ifdef __cplusplus
#define NULL 0
#else
#define NULL ((void *)0)
#endif
#endif

In several headers which kind of hints that 0 has an acceptable
conversion to pointers if __cplusplus is defined.

So I'm guessing that 0 converts to a char * which is a default
constructor for foo, so it is constructed and passed to foobar.

To my knowlegde this is not standard C++ behavior, so it is probably a
convient feature for VC++ 6. I hope that helps.

Whats funny is... char *p = (const unsigned long)0; won't work.
hehe...

Chris Underwood


"Torstein Hansen" <torsteinRemoveThis (AT) hansen (DOT) as> wrote

Quote:
The following code gives us a little headache.

Calls to foobar with parameter u0 (set to 0) compiles without warnings,
but using parameter u1 (equal to 1) gives a compiler error "Cannot
convert from const unsigned long to const class foo &"

I really can't see why it would make any difference what numerical value
is used.

Anyone care to explain? Is it me or the compiler that is half-blind?

code

class foo
{
public:
foo();
foo(const foo &f);
foo(char* pc);
};

class bar
{
public:
bar();

bool foobar(const foo& rf);
};

void main()
{
bar b;
const unsigned long u0 = 0;
const unsigned long u1 = 1;

b.foobar(u0);
b.foobar(u1);
}

/code

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
bert hubert
Guest





PostPosted: Thu Feb 19, 2004 6:18 pm    Post subject: Re: Compiler error or? Microsoft VC++ v6.0 Reply with quote

On 2004-02-18, Torstein Hansen <torsteinRemoveThis (AT) hansen (DOT) as> wrote:
Quote:
The following code gives us a little headache.

Calls to foobar with parameter u0 (set to 0) compiles without warnings,
but using parameter u1 (equal to 1) gives a compiler error "Cannot
convert from const unsigned long to const class foo &"

I'm no language lawyer, but expecting an unsigned long to be silently cast
into a char* is wrong. They do that in C :-)

For 0, some special rules might apply (not aware of any, but 0 is somewhat
special), but don't count on it. Whatever the language says, you are in
scary territory here. Don't do it.


--
http://www.PowerDNS.com/ Open Source Database Driven Nameserver
http://lartc.org Linux Advanced Routing & Traffic Control HOWTO

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
Steve Dewhurst
Guest





PostPosted: Thu Feb 19, 2004 6:22 pm    Post subject: Re: Compiler error or? Microsoft VC++ v6.0 Reply with quote

"Torstein Hansen" <torsteinRemoveThis (AT) hansen (DOT) as> wrote

Quote:
The following code gives us a little headache.

Calls to foobar with parameter u0 (set to 0) compiles without warnings,
but using parameter u1 (equal to 1) gives a compiler error "Cannot
convert from const unsigned long to const class foo &"

I really can't see why it would make any difference what numerical value
is used.

An initialized constant integral object is a constant-expression (what
used to be known as an "integer constant expression"). A
constant-expression with a value of 0 may be converted to a null
pointer value. A constant-expression with a value of 1 may not. As
an experiment, try removing the "const" on the declaration of u0 and
see what happens.

Steve

Steve Dewhurst
www.semantics.org

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
PeteK
Guest





PostPosted: Fri Feb 20, 2004 12:49 am    Post subject: Re: Compiler error or? Microsoft VC++ v6.0 Reply with quote

"Torstein Hansen" <torsteinRemoveThis (AT) hansen (DOT) as> wrote

Quote:
The following code gives us a little headache.

Calls to foobar with parameter u0 (set to 0) compiles without warnings,
but using parameter u1 (equal to 1) gives a compiler error "Cannot
convert from const unsigned long to const class foo &"

I really can't see why it would make any difference what numerical value
is used.

Anyone care to explain? Is it me or the compiler that is half-blind?

code

class foo
{
public:
foo();
foo(const foo &f);
foo(char* pc);
};

class bar
{
public:
bar();

bool foobar(const foo& rf);
};

void main()
{
bar b;
const unsigned long u0 = 0;
const unsigned long u1 = 1;

b.foobar(u0);
b.foobar(u1);
}

/code

OK, It's 1am and I've just got in from the pub,

but I'd say u0 is zero is NULL is a valid char * which converts to a
foo. u1 is a non-zero, which doesn't.

PeteK

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
John Sun
Guest





PostPosted: Fri Feb 20, 2004 12:50 am    Post subject: Re: Compiler error or? Microsoft VC++ v6.0 Reply with quote

b.foobar(u0);
b.foobar(u1);

when you call foobar with u0, I think 0 can be evaluated as a null, so foo
constructor will accept it, actually, you can debug it when passing 0, and
see how the program flows.

While you pass -1, there is no foo constructor which can take unsigned long
...

Just simple try that ..

const unsigned long u0 = 0;
const unsigned long u1 = 1;

char* pc0, pc1;
pc0=u0;
pc1=u1;

And see what kind of error you will get..

J.W.



"Torstein Hansen" <torsteinRemoveThis (AT) hansen (DOT) as> wrote

Quote:
The following code gives us a little headache.

Calls to foobar with parameter u0 (set to 0) compiles without warnings,
but using parameter u1 (equal to 1) gives a compiler error "Cannot
convert from const unsigned long to const class foo &"

I really can't see why it would make any difference what numerical value
is used.

Anyone care to explain? Is it me or the compiler that is half-blind?

code

class foo
{
public:
foo();
foo(const foo &f);
foo(char* pc);
};

class bar
{
public:
bar();

bool foobar(const foo& rf);
};

void main()
{
bar b;
const unsigned long u0 = 0;
const unsigned long u1 = 1;

b.foobar(u0);
b.foobar(u1);
}

/code

Torstein Hansen
(Remove "RemoveThis" to answer by mail)

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
Sharad Kala
Guest





PostPosted: Fri Feb 20, 2004 12:53 am    Post subject: Re: Compiler error or? Microsoft VC++ v6.0 Reply with quote


"Torstein Hansen" <torsteinRemoveThis (AT) hansen (DOT) as> wrote

Quote:
The following code gives us a little headache.

Calls to foobar with parameter u0 (set to 0) compiles without warnings,
but using parameter u1 (equal to 1) gives a compiler error "Cannot
convert from const unsigned long to const class foo &"

I really can't see why it would make any difference what numerical value
is used.

Anyone care to explain? Is it me or the compiler that is half-blind?

Actually you :-)

Quote:
code

class foo
{
public:
foo();
foo(const foo &f);
foo(char* pc);
};

class bar
{
public:
bar();

bool foobar(const foo& rf);
};

void main()
{
bar b;
const unsigned long u0 = 0;
const unsigned long u1 = 1;

b.foobar(u0);
b.foobar(u1);
}


A value of 0 can be implicitly converted to a char* so your b.foobar(u0);
works through. Same is not the case with your call b.foobar(u1).

Try this -
void *i = 0; // Works
void *j = 1; // Error

Best wishes,
Sharad



[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
Maciej Sobczak
Guest





PostPosted: Fri Feb 20, 2004 1:05 am    Post subject: Re: Compiler error or? Microsoft VC++ v6.0 Reply with quote

Hi,

Torstein Hansen wrote:

Quote:
The following code gives us a little headache.

Calls to foobar with parameter u0 (set to 0) compiles without warnings,
but using parameter u1 (equal to 1) gives a compiler error "Cannot
convert from const unsigned long to const class foo &"

I think that the compiler got trapped in its own optimizations.

Quote:
I really can't see why it would make any difference what numerical value
is used.

If you use const unsigned long (the const part is important here), then
the compiler may optimize the use of your variables away, substituting
plain values whenever the variable is used (if you've learned a bit of
assembly language, the difference is between indirect and immediate
addressing - the immediate one, when the hardcoded value is used, is
faster), so you example becomes:

b.foobar(0);
b.foobar(1);

The problem is that both calls need to use a foo constructor.
In the case of b.foobar(0), the foo(char *pc) constructor is used,
because 0 can be converted to a null pointer value (the Standard gives
the explicit license for this to happen and in most implementations NULL
is a macro that expands to 0).
In the case of b.foobar(1), none of the foo's constructors can be used
(there is no conversion from integral literal other than 0 to pointers)
and you get the message "Cannot convert from const unsigned long to
const class foo &".

Quote:
Anyone care to explain? Is it me or the compiler that is half-blind?

It is the Standard that leads us to confusions like this and the
compiler that was trapped by its own optimizations. It should not
compile neither of the calls (try without "const" to see).

--
Maciej Sobczak : http://www.msobczak.com/
Programming : http://www.msobczak.com/prog/


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
Friedhelm Hoerner
Guest





PostPosted: Fri Feb 20, 2004 1:10 am    Post subject: Re: Compiler error or? Microsoft VC++ v6.0 Reply with quote

"Torstein Hansen" <torsteinRemoveThis (AT) hansen (DOT) as> wrote

Quote:
The following code gives us a little headache.

Calls to foobar with parameter u0 (set to 0) compiles without warnings,
but using parameter u1 (equal to 1) gives a compiler error "Cannot
convert from const unsigned long to const class foo &"

I really can't see why it would make any difference what numerical value
is used.

Anyone care to explain? Is it me or the compiler that is half-blind?

code

class foo
{
public:
foo();
foo(const foo &f);
foo(char* pc);
};

class bar
{
public:
bar();

bool foobar(const foo& rf);
};

void main()
{
bar b;
const unsigned long u0 = 0;
const unsigned long u1 = 1;


you need a "const foo& rf" to call foobar...

Quote:
b.foobar(u0);

.... u0 is 0 and may be interpreted as a NULL-Pointer therefore foo's
constructor
foo(char* pc) can be called to create the temporary object.

Quote:
b.foobar(u1);

.... u1 is 1, there's no conversion to char*, therefore foo has no
matching constructor.

Quote:
}


Friedhelm

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
kanze@gabi-soft.fr
Guest





PostPosted: Fri Feb 20, 2004 11:23 am    Post subject: Re: Compiler error or? Microsoft VC++ v6.0 Reply with quote

"Torstein Hansen" <torsteinRemoveThis (AT) hansen (DOT) as> wrote


Quote:
The following code gives us a little headache.

Calls to foobar with parameter u0 (set to 0) compiles without
warnings, but using parameter u1 (equal to 1) gives a compiler error
"Cannot convert from const unsigned long to const class foo &"

I really can't see why it would make any difference what numerical
value is used.

The parameters in question are const, so u0 is a null pointer constant,
which can be converted to any pointer type.

Try dropping the const, and see what happens.

--
James Kanze GABI Software mailto:kanze (AT) gabi-soft (DOT) fr
Conseils en informatique orientée objet/ http://www.gabi-soft.fr
Beratung in objektorientierter Datenverarbeitung
11 rue de Rambouillet, 78460 Chevreuse, France, +33 (0)1 30 23 45 16

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
Display posts from previous:   
Post new topic   Reply to topic    C++Talk.NET Forum Index -> C++ Language (Moderated) All times are GMT
Goto page 1, 2  Next
Page 1 of 2

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2006 phpBB Group
SEO toolkit © 2004-2006 webmedic.