conversion from const type* to type* allowed?

  • Thread starter Michal Nazarewicz
  • Start date
M

Michal Nazarewicz

The following code compiles fine (with warnings though) under GCC with
-pedantic and -ansi arguments:

#v+
int main(void) {
const int a = 0;
int *p = &a;
return 0;
}
#v-

so am I missing something, GCC is buggy or it is really allowed to
convert a pointer to const type to pointer to type?
 
I

Ian Collins

Michal said:
The following code compiles fine (with warnings though) under GCC with
-pedantic and -ansi arguments:

#v+
int main(void) {
const int a = 0;
int *p = &a;
return 0;
}
#v-

so am I missing something, GCC is buggy or it is really allowed to
convert a pointer to const type to pointer to type?
Const is broken in C, that's why one shouldn't ignore compiler warnings!
 
E

Eric Sosman

Michal Nazarewicz wrote On 01/04/07 15:55,:
The following code compiles fine (with warnings though) under GCC with
-pedantic and -ansi arguments:

#v+
int main(void) {
const int a = 0;
int *p = &a;
return 0;
}
#v-

so am I missing something, GCC is buggy or it is really allowed to
convert a pointer to const type to pointer to type?

From back to front: It is not allowed, GCC is not buggy
(not in this regard, anyway), and you are in fact missing
something. What you're missing is that the C Standard makes
no distinction between error messages, warning messages,
informative messages, and spirit messages from the Great
Beyond: They are all merely "diagnostics." Once the compiler
has emitted a "diagnostic" for the erroneous construct, it
is under no obligation to halt compilation or reject the
program[*], it may (if it feels like it) emit the diagnostic
and translate the program anyhow.

There's a GCC option ("-Werror"?) that turns "warnings"
into "fatal errors" if you prefer.

[*] Exception: The compiler is required to reject a
module containing a non-suppressed #error directive.
 
K

Keith Thompson

Michal Nazarewicz said:
The following code compiles fine (with warnings though) under GCC with
-pedantic and -ansi arguments:

#v+
int main(void) {
const int a = 0;
int *p = &a;
return 0;
}
#v-

so am I missing something, GCC is buggy or it is really allowed to
convert a pointer to const type to pointer to type?

The implicit conversion is a constraint violation. A conforming
compiler's only obligation in the presence of a constraint violation
is to issue a diagnostic. gcc meets this requirement by printing a
warning.

The only case where a compiler is actually required to reject a
translation unit is when it contains a "#error" directive.
 
A

Al Balmer

The following code compiles fine (with warnings though)

If it had warnings, it did not compile fine. Just remember that the
compiler is actually too dumb to know the difference between a serious
error and a trivial one, though it like to pretend it does.

Strive to have all your programs compile cleanly without errors or
warnings. There are cases where warnings can be ignored*, but only if
you understand exactly what caused them and know for a fact that it
won't be a problem.

*One which comes to mind is an HP-UX warning that is issued whenever
you use "const". It just tells you that using const improperly is bad,
 
R

Richard Heathfield

Al Balmer said:

Strive to have all your programs compile cleanly without errors or
warnings. There are cases where warnings can be ignored*, but only if
you understand exactly what caused them and know for a fact that it
won't be a problem.

Perhaps "overruled" would be a better word than "ignored". When gcc tells me
that I've only partly initialised an aggregate object - e.g. mystruct s =
{0}; - I take due note of the warning, and check that the initialisation is
correct. Actually, this is such a frequent occurrence that I suppose
"ignored" is pretty accurate in that case, so let me find a different
example (taken from real code this time):

Dest->n = in & 0xff;

Dest->n has type unsigned char. in is a long int (which, incidentally, is
known to be non-negative by this stage in the proceedings). By the rules of
C, in & 0xff must must must must must be in the range of unsigned char, so
I know for sure that it will fit into Dest->n - and yet one of my
compilers issues a diagnostic message saying that information might be lost
in this assignment. It can't possibly be - but the compiler isn't quite
bright enough to work this out, so it warns me.

And it's a reasonable warning, on the whole. So I let the compiler warn me,
and I look at the warning, and I check that it really is okay. If it is, I
may add a comment to the code to save me a little time next time through,
but by paying attention to the warning at least the first time it appears,
I have given myself the opportunity to check out a potential bug.
 
P

Peter Nilsson

Eric said:
Michal Nazarewicz wrote On 01/04/07 15:55,:
... The compiler is required to reject a
module containing a non-suppressed #error directive.

That is true of C99, but rejection under #error is not a requirement of
C90
implementations. However, the C90 implementation the OP is using will.
 
M

Michal Nazarewicz

Al Balmer said:
If it had warnings, it did not compile fine.

True and I always check all the warnings compiler gives me but at this
point I was shocked that compiler generated an executable where
implicit conversion from pointer to const type to pointer to type was
done.
 
M

Michal Nazarewicz

Eric Sosman said:
Michal Nazarewicz wrote On 01/04/07 15:55,:
The following code compiles fine (with warnings though) under GCC with
-pedantic and -ansi arguments:

#v+
int main(void) {
const int a = 0;
int *p = &a;
return 0;
}
#v-

so am I missing something, GCC is buggy or it is really allowed to
convert a pointer to const type to pointer to type?

From back to front: It is not allowed, GCC is not buggy
(not in this regard, anyway), and you are in fact missing
something. What you're missing is that the C Standard makes
no distinction between error messages, warning messages,
informative messages, and spirit messages from the Great
Beyond: They are all merely "diagnostics." Once the compiler
has emitted a "diagnostic" for the erroneous construct, it
is under no obligation to halt compilation or reject the
program[*], it may (if it feels like it) emit the diagnostic
and translate the program anyhow.

Thanks for explanation, I wasn't aware of such behaviour even though
it sounds rather strange to me.
There's a GCC option ("-Werror"?) that turns "warnings"
into "fatal errors" if you prefer.

That'd be too much. I use a -Wpadded switch which produces warnings
that some of them are to be ignored.
 
J

jaysome

Al Balmer said:

Strive to have all your programs compile cleanly without errors or
warnings. There are cases where warnings can be ignored*, but only if
you understand exactly what caused them and know for a fact that it
won't be a problem.

Perhaps "overruled" would be a better word than "ignored". When gcc tells me
that I've only partly initialised an aggregate object - e.g. mystruct s =
{0}; - I take due note of the warning, and check that the initialisation is
correct. Actually, this is such a frequent occurrence that I suppose
"ignored" is pretty accurate in that case, so let me find a different
example (taken from real code this time):

Dest->n = in & 0xff;

Dest->n has type unsigned char. in is a long int (which, incidentally, is
known to be non-negative by this stage in the proceedings). By the rules of
C, in & 0xff must must must must must be in the range of unsigned char, so
I know for sure that it will fit into Dest->n - and yet one of my
compilers issues a diagnostic message saying that information might be lost
in this assignment. It can't possibly be - but the compiler isn't quite
bright enough to work this out, so it warns me.

And it's a reasonable warning, on the whole. So I let the compiler warn me,
and I look at the warning, and I check that it really is okay. If it is, I
may add a comment to the code to save me a little time next time through,
but by paying attention to the warning at least the first time it appears,
I have given myself the opportunity to check out a potential bug.


I'd take charge of the matter and get rid of the compiler warning
altogether. You could get rid of it this way:

Dest->n = (unsigned char)(in & 0xff);

You could also get rid of it using compiler-specific pragmas, for
example:

#ifdef _MSC_VER
#pragma warning(disable:4244)
#endif
Dest->n = in & 0xff;
#ifdef _MSC_VER
#pragma warning(default:4244)
#endif

I'd choose the former, since it is much easier to implement, and I
know what I'm doing, and a cast in this case is worth getting rid of
the bogus compiler warning.
 
C

Christopher Benson-Manica

Richard Heathfield said:
Perhaps "overruled" would be a better word than "ignored".

int *foo=42;

"Objection, your honor! This construct makes a pointer from an
integer without a cast!"

Sometimes overruling the objections of the General Compiler Council
can be cause for disbarment :)
 
R

Richard Heathfield

jaysome said:

I'd take charge of the matter and get rid of the compiler warning
altogether. You could get rid of it this way:

Dest->n = (unsigned char)(in & 0xff);


True, but adding spurious casts to code to silence diagnostic messages does
not add value to the code. It doesn't do anything good, and it doesn't stop
anything bad happening. All it does is turn your eyes off.
You could also get rid of it using compiler-specific pragmas,

....and have gcc play nethack with you. Yeah, right. :)
 
E

Eric Sosman

Peter said:
That is true of C99, but rejection under #error is not a requirement of
C90
implementations. However, the C90 implementation the OP is using will.

If C99 were a human child she would be almost eight years
old and partway through the second grade. She would know how
to add and subtract, and would be on the verge of learning
multiplication. She would be able to read. She might be
taking violin lessons (with wide strings, no doubt). She would
be computer-literate. She would be an accepted, albeit junior,
member of society.

Alas! that over this bright beginning should hang the grim
shadow of noxious doom! For though she seems healthy and happy
today, her family is congenitally short-lived: her elder brother
ANSI succumbed before he reached his teens, and a similar fate
awaits poor C99. Another year or two, say the grave and sorrowful
doctors, or three at the most, and >sob< she will be gone.

When the grim day arrives, will it be said that she was never
a "real" child? Will she go to her grave unmourned, unloved,
always passed over in favor of her long-gone brother's ghost?
Don't be so heartless: it is in your power to give her a brief
moment of acknowledgment before she's gone. Make a child happy.

"Be not the first by whom the new is tried,
Nor yet the last to lay the old aside."
-- Alexander Pope
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,756
Messages
2,569,535
Members
45,008
Latest member
obedient dusk

Latest Threads

Top