By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
443,705 Members | 2,017 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 443,705 IT Pros & Developers. It's quick & easy.

printf() error with long double and null pointer.

P: n/a
Hello all,

Before stating my question, I should mention that I'm fairly new to C.

Now, I attempted a small demo that prints out the values of C's numeric
types, both uninitialised and after assigning them their maximum defined
values. However, the output of printf() for the long double 'ld' and the
pointer of type void 'v_p', after initialisation don't seem to be right.

The compiler used was gcc (mingw) with '-Wall', '-std=c99' and
'-pedantic' switches. No warnings were emitted. Incidentally the MS
Visual C++ 2003 compiler's output seems okay. I give them both below:

gcc's output:
ld == -1.#QNAN0
or -1.#QNAN
v_p == FFFFFFFF

msvc's output:
ld == 17976931348623157000000000000000000000000000000000 0000000000000000
00000000000000000000000000000000000000000000000000 0000000000000000000000
00000000000000000000000000000000000000000000000000 0000000000000000000000
00000000000000000000000000000000000000000000000000 0000000000000000000000
000000000000000000000000000.000000
or 1.79769e+308
v_p == 00000000

I thought null pointers had a value of zero. Why is gcc's executable
printing ffffffffh? Also the value of 'ld' seems to be wrong.

The code for the demo is:
#include <stdio.h>
#include <limits.h>
#include <float.h>

int main(void) {
char c;
unsigned char uc;
short s;
unsigned short us;
int i;
unsigned int ui;
long l;
unsigned long ul;
float f;
double d;
long double ld;
void *v_p;

printf("c == %c\n\tor %d\nuc == %c\n\tor %u\ns == %hd\nus == %hu\n"
"i == %d\nui == %u\nl == %ld\nul == %lu\nf == %f\n\tor %g\n"
"d == %lf\n\tor %g\nld == %Lf\n\tor %Lg\nv_p == %p\n",
c,c,uc,uc,s,us,i,ui,l,ul,f,f,d,d,ld,ld,v_p);

puts("Initialising them with their maximum allowed values...");
c = CHAR_MAX;
uc = UCHAR_MAX;
s = SHRT_MAX;
us = USHRT_MAX;
i = INT_MAX;
ui = UINT_MAX;
l = LONG_MAX;
ul = ULONG_MAX;
f = FLT_MAX;
d = DBL_MAX;
ld = LDBL_MAX;
puts("Initialising v_p with NULL...");
v_p = NULL;

printf("c == %c\n\tor %d\nuc == %c\n\tor %u\ns == %hd\nus == %hu\n"
"i == %d\nui == %u\nl == %ld\nul == %lu\nf == %f\n\tor %g\n"
"d == %lf\n\tor %g\nld == %Lf\n\tor %Lg\nv_p == %p\n",
c,c,uc,uc,s,us,i,ui,l,ul,f,f,d,d,ld,ld,v_p);
return 0;
}

Where is the mistake?
Thanks for all the help.
Feb 24 '06 #1
Share this Question
Share on Google+
69 Replies


P: n/a
fieldfallow <fi*********@gmail.com> wrote in news:dtmt1n$1g3$1
@emma.aioe.org:
I thought null pointers had a value of zero. Why is gcc's executable
printing ffffffffh?


http://c-faq.com/null/index.html

Sinan
--
A. Sinan Unur <1u**@llenroc.ude.invalid>
(reverse each component and remove .invalid for email address)
Feb 24 '06 #2

P: n/a
fieldfallow wrote:

Hello all,

Before stating my question,
I should mention that I'm fairly new to C.

Now, I attempted a small demo that prints out
the values of C's numeric types, both uninitialised


Accessing uninitialised values like that,
causes undefined behavior in your program.
The undefined behavior can show up in any part
of the program's execution.

--
pete
Feb 24 '06 #3

P: n/a
pete wrote:
fieldfallow wrote:
Hello all,

Before stating my question,
I should mention that I'm fairly new to C.

Now, I attempted a small demo that prints out
the values of C's numeric types, both uninitialised


Accessing uninitialised values like that,
causes undefined behavior in your program.
The undefined behavior can show up in any part
of the program's execution.


Does even printing out the values cause undefined behaviour? Is any
other operation legal, or must I assign them values before I do anything
with them?

Thanks for your answers. The C book I currently have is not very clear
on this point.
Feb 24 '06 #4

P: n/a


"fieldfallow" <fi*********@gmail.com> wrote in message
news:dt**********@emma.aioe.org...
Hello all,

Before stating my question, I should mention that I'm fairly new to C.

Now, I attempted a small demo that prints out the values of C's numeric
types, both uninitialised and after assigning them their maximum defined
values. However, the output of printf() for the long double 'ld' and the
pointer of type void 'v_p', after initialisation don't seem to be right.

The compiler used was gcc (mingw) with '-Wall', '-std=c99' and
'-pedantic' switches. No warnings were emitted. Incidentally the MS
Visual C++ 2003 compiler's output seems okay. I give them both below:

gcc's output:
ld == -1.#QNAN0
or -1.#QNAN
v_p == FFFFFFFF

msvc's output:
ld == 17976931348623157000000000000000000000000000000000 0000000000000000
00000000000000000000000000000000000000000000000000 0000000000000000000000
00000000000000000000000000000000000000000000000000 0000000000000000000000
00000000000000000000000000000000000000000000000000 0000000000000000000000
000000000000000000000000000.000000
or 1.79769e+308
v_p == 00000000

I thought null pointers had a value of zero. Why is gcc's executable
printing ffffffffh? Also the value of 'ld' seems to be wrong.

The code for the demo is:
#include <stdio.h>
#include <limits.h>
#include <float.h>

int main(void) {
char c;
unsigned char uc;
short s;
unsigned short us;
int i;
unsigned int ui;
long l;
unsigned long ul;
float f;
double d;
long double ld;
void *v_p;

printf("c == %c\n\tor %d\nuc == %c\n\tor %u\ns == %hd\nus == %hu\n"
"i == %d\nui == %u\nl == %ld\nul == %lu\nf == %f\n\tor %g\n"
"d == %lf\n\tor %g\nld == %Lf\n\tor %Lg\nv_p == %p\n",
c,c,uc,uc,s,us,i,ui,l,ul,f,f,d,d,ld,ld,v_p);

puts("Initialising them with their maximum allowed values...");
c = CHAR_MAX;
uc = UCHAR_MAX;
s = SHRT_MAX;
us = USHRT_MAX;
i = INT_MAX;
ui = UINT_MAX;
l = LONG_MAX;
ul = ULONG_MAX;
f = FLT_MAX;
d = DBL_MAX;
ld = LDBL_MAX;
puts("Initialising v_p with NULL...");
v_p = NULL;

printf("c == %c\n\tor %d\nuc == %c\n\tor %u\ns == %hd\nus == %hu\n"
"i == %d\nui == %u\nl == %ld\nul == %lu\nf == %f\n\tor %g\n"
"d == %lf\n\tor %g\nld == %Lf\n\tor %Lg\nv_p == %p\n",
c,c,uc,uc,s,us,i,ui,l,ul,f,f,d,d,ld,ld,v_p);
return 0;
}

Where is the mistake?
Thanks for all the help.


Works for me running gcc on Cygwin.

%lf (alternative to %f) for double is a new feature in C99. Does your
printf support it?

If you're not on Linux or Cygwin, you may be using your system's libc, in
which case you get what you get, notwithstanding the C99 flag.
--
RSH
Feb 24 '06 #5

P: n/a
fieldfallow wrote:

pete wrote:
fieldfallow wrote:
Hello all,

Before stating my question,
I should mention that I'm fairly new to C.

Now, I attempted a small demo that prints out
the values of C's numeric types, both uninitialised
Accessing uninitialised values like that,
causes undefined behavior in your program.
The undefined behavior can show up in any part
of the program's execution.


Does even printing out the values cause undefined behaviour?


Yes.
Is any
other operation legal, or must I assign them values before I do
anything with them?


For uninitialised objects,
you can only portably do operations which don't access the values.
That's pretty much limited to having the variables be
operands of the address operator and or the sizeof operator.

--
pete
Feb 24 '06 #6

P: n/a
In article <dt**********@emma.aioe.org>,
fieldfallow <fi*********@gmail.com> wrote:
Accessing uninitialised values like that,
causes undefined behavior in your program.
The undefined behavior can show up in any part
of the program's execution.
Does even printing out the values cause undefined behaviour?


Yes, but I would be surprised if it caused the behaviour shown.
Try removing the first printf and see if you still get the same
results for the second.

-- Richard
Feb 24 '06 #7

P: n/a
Richard Tobin wrote:
In article <dt**********@emma.aioe.org>,
fieldfallow <fi*********@gmail.com> wrote:
Accessing uninitialised values like that,
causes undefined behavior in your program.
The undefined behavior can show up in any part
of the program's execution.

Does even printing out the values cause undefined behaviour?


Yes, but I would be surprised if it caused the behaviour shown.
Try removing the first printf and see if you still get the same
results for the second.


Yes. Even after commenting out the first printf(), I still get the same
wrong output. Would this indicate a fault in the particular toolchain,
i.e. gcc (MinGW)?

The output is:
Initialising them with their maximum allowed values...
Initialising v_p with NULL...
c == 
or 127
uc == ÿ
or 255
s == 32767
us == 65535
i == 2147483647
ui == 4294967295
l == 2147483647
ul == 4294967295
f == 340282346638528860000000000000000000000.000000
or 3.40282e+038
d == 17976931348623157000000000000000000000000000000000 000000000000000000
00000000000000000000000000000000000000000000000000 000000000000000000
00000000000000000000000000000000000000000000000000 000000000000000000
00000000000000000000000000000000000000000000000000 000000000000000000
0000000000000000000000000000000000000.000000
or 1.79769e+308
ld == -1.#QNAN0
or -1.#QNAN
v_p == FFFFFFFF

Thanks.
Feb 24 '06 #8

P: n/a
fieldfallow wrote:
ld == -1.#QNAN0
or -1.#QNAN


That result is also wrong.

Are you using still using %lf to output doubles?

%f is for both doubles and floats.

C99 allows %lf for doubles, but most compilers are C90
where using %lf to output a double is also undefined.

--
pete
Feb 24 '06 #9

P: n/a
Robin Haigh wrote:
Works for me running gcc on Cygwin.
Strange. My compiler is gcc 3.4.5 for MinGW 5.0
%lf (alternative to %f) for double is a new feature in C99. Does your
printf support it?
I think so. The output for the double seems to be correct. Only those of
the long double and void pointer seem to be wrong. I'm saying this
because the MS Visual C++ 2003 toolkit compiler's output for the double
tallies with gcc. In addition the max. for long double is the same as
double and void pointer prints out zero after assigning NULL to it.
If you're not on Linux or Cygwin, you may be using your system's libc, in
which case you get what you get, notwithstanding the C99 flag.


In this case, the MSVC compiled executable should also exhibit the same
error, shouldn't it.

Anyway, this seems to be heading a bit off-topic here. Maybe a MinGW
group would be better.

Thanks everyone for your help.
Feb 24 '06 #10

P: n/a
In article <43**************@gmail.com>,
fieldfallow <fi*********@gmail.com> wrote:
Yes. Even after commenting out the first printf(), I still get the same
wrong output. Would this indicate a fault in the particular toolchain,
i.e. gcc (MinGW)?


Perhaps a bug in the handling of long double. Take out the long
double values and see if the pointer has the expected value. Or put
in some plain integers after the long doubles and see if they are
wrong. (As far as I know, %p is not required to print any particular
value for null pointers, but it will almost certainly be zero.)

-- Richard
Feb 24 '06 #11

P: n/a
pete wrote:

fieldfallow wrote:
ld == -1.#QNAN0
or -1.#QNAN


That result is also wrong.

Are you using still using %lf to output doubles?

%f is for both doubles and floats.

C99 allows %lf for doubles, but most compilers are C90
where using %lf to output a double is also undefined.


I'm suggesting that the error may have occured just
before the long double output.

--
pete
Feb 24 '06 #12

P: n/a
pete wrote:
fieldfallow wrote:
ld == -1.#QNAN0
or -1.#QNAN


That result is also wrong.

Are you using still using %lf to output doubles?

%f is for both doubles and floats.

C99 allows %lf for doubles, but most compilers are C90
where using %lf to output a double is also undefined.


Okay, I switched to %f for both floats and doubles and kept the first
printf() commented out, and still the same error.

Output:
Initialising them with their maximum allowed values...
Initialising v_p with NULL...
c == 
or 127
uc == ÿ
or 255
s == 32767
us == 65535
i == 2147483647
ui == 4294967295
l == 2147483647
ul == 4294967295
f == 340282346638528860000000000000000000000.000000
or 3.40282e+038
d == 17976931348623157000000000000000000000000000000000 0
00000000000000000000000000000000000000000000000000 000000
00000000000000000000000000000000000000000000000000 000000
00000000000000000000000000000000000000000000000000 000000
00000000000000000000000000000000000000000000000000 000000
0000000000000000000000000000000000.000000
or 1.79769e+308
ld == -1.#QNAN0
or -1.#QNAN
v_p == FFFFFFFF

Code is:
#include <stdio.h>
#include <limits.h>
#include <float.h>

int main(void) {
char c;
unsigned char uc;
short s;
unsigned short us;
int i;
unsigned int ui;
long l;
unsigned long ul;
float f;
double d;
long double ld;
void *v_p;
/*
printf("c == %c\n\tor %d\nuc == %c\n\tor %u\ns == %hd\nus == %hu\n"
"i == %d\nui == %u\nl == %ld\nul == %lu\nf == %f\n\tor %g\n"
"d == %lf\n\tor %g\nld == %Lf\n\tor %Lg\nv_p == %p\n",
c,c,uc,uc,s,us,i,ui,l,ul,f,f,d,d,ld,ld,v_p);
*/
puts("Initialising them with their maximum allowed values...");
c = CHAR_MAX;
uc = UCHAR_MAX;
s = SHRT_MAX;
us = USHRT_MAX;
i = INT_MAX;
ui = UINT_MAX;
l = LONG_MAX;
ul = ULONG_MAX;
f = FLT_MAX;
d = DBL_MAX;
ld = LDBL_MAX;
puts("Initialising v_p with NULL...");
v_p = NULL;

printf("c == %c\n\tor %d\nuc == %c\n\tor %u\ns == %hd\nus == %hu\n"
"i == %d\nui == %u\nl == %ld\nul == %lu\nf == %f\n\tor %g\n"
"d == %f\n\tor %g\nld == %Lf\n\tor %Lg\nv_p == %p\n",
c,c,uc,uc,s,us,i,ui,l,ul,f,f,d,d,ld,ld,v_p);
return 0;
}

Thanks.
Feb 24 '06 #13

P: n/a
Richard Tobin wrote:
In article <43**************@gmail.com>,
fieldfallow <fi*********@gmail.com> wrote:
Yes. Even after commenting out the first printf(), I still get the same
wrong output. Would this indicate a fault in the particular toolchain,
i.e. gcc (MinGW)?


Perhaps a bug in the handling of long double. Take out the long
double values and see if the pointer has the expected value. Or put
in some plain integers after the long doubles and see if they are
wrong. (As far as I know, %p is not required to print any particular
value for null pointers, but it will almost certainly be zero.)

-- Richard


Your right Richard. After completely removing the long double from
printf(), the void pointer's value is printed out as 00000000.

Also, declaring and initialising the long double with LDBL_MAX, but not
attempting to pass it to printf() also gives the correct output for the
void pointer.

So I guess it appears to be a bug in the printf()'s handling of long
double arguments.

Maybe it's been corrected by any recent patches, though my MinGW
distribution was installed only two months before.

Thanks for your help.
Feb 24 '06 #14

P: n/a
fieldfallow <fi*********@gmail.com> wrote:
Richard Tobin wrote:
In article <dt**********@emma.aioe.org>,
fieldfallow <fi*********@gmail.com> wrote:
Accessing uninitialised values like that,
causes undefined behavior in your program.
The undefined behavior can show up in any part
of the program's execution.
Does even printing out the values cause undefined behaviour?


Yes, but I would be surprised if it caused the behaviour shown.
Try removing the first printf and see if you still get the same
results for the second.


Yes. Even after commenting out the first printf(), I still get the same
wrong output.


It does that for me, too[0]. When I remove the references to long
doubles in the printf(), it prints the expected[1] value for v_p, too.
It appears at first glance that gcc and the MinGW library are not in
accord over the size of a long double. How pernicious.

Try this: print (using sizeof) the size of your double and long double.
Dev-C++ on this computer says 8 and 12, respectively. But the headers
claim that long double is the same as double, and all values in
<float.h> for LDBL_* are the same as for DBL_*. Presumably, *printf()
assume that sizeof (double) == sizeof (long double), too.
Would this indicate a fault in the particular toolchain, i.e. gcc (MinGW)?


Yes.

Anyone know the right channel to report this to MinGW?

Richard

[0] Even when inserting the l in the second %g...
[1] Although not required.
Feb 24 '06 #15

P: n/a
fieldfallow wrote:
ld == -1.#QNAN0
or -1.#QNAN
v_p == FFFFFFFF


The pointer is allowed to print out any way that
the implementation defines it,
but the long double output is just wrong.

I can't find any problems in the rest of your code.
I'm beginning to suspect your implementation.

For debugging,
it's good to see the smallest code which exhibits the problem.
Try this:

#include <stdio.h>
#include <limits.h>
#include <float.h>

int main(void)
{
float f;
double d;
long double ld;
void *v_p;
puts("Initialising them with their maximum allowed values...");
puts("Initialising v_p with NULL...");

f = FLT_MAX;
d = DBL_MAX;
ld = LDBL_MAX;
v_p = NULL;

printf( "f == %g\n"
"d == %g\n"
"ld == %Lg\n"
"v_p == %p\n"
, f, d, ld, v_p);
return 0;
}

--
pete
Feb 24 '06 #16

P: n/a
pete wrote:
fieldfallow wrote:
ld == -1.#QNAN0
or -1.#QNAN
v_p == FFFFFFFF
The pointer is allowed to print out any way that
the implementation defines it,
but the long double output is just wrong.

I can't find any problems in the rest of your code.
I'm beginning to suspect your implementation.


Yes. Especially, when printf() is passed a long double argument,
arguments after it seem to get trashed.
For debugging,
it's good to see the smallest code which exhibits the problem.
Try this:

#include <stdio.h>
#include <limits.h>
#include <float.h>

int main(void)
{
float f;
double d;
long double ld;
void *v_p;
puts("Initialising them with their maximum allowed values...");
puts("Initialising v_p with NULL...");

f = FLT_MAX;
d = DBL_MAX;
ld = LDBL_MAX;
v_p = NULL;

printf( "f == %g\n"
"d == %g\n"
"ld == %Lg\n"
"v_p == %p\n"
, f, d, ld, v_p);
return 0;
}


Compiled with gcc -Wall -std=c99 -pedantic
Output is:
Initialising them with their maximum allowed values...
Initialising v_p with NULL...
f == 3.40282e+038
d == 1.79769e+308
ld == -1.#QNAN
v_p == 00007FFE

At this point it seems to be an error in my implementation's printf()
regarding long doubles. I'll writes some more demos and then try
reinstalling MinGW.

Thanks for your help.
Feb 24 '06 #17

P: n/a
On 2006-02-24, A. Sinan Unur <1u**@llenroc.ude.invalid> wrote:
fieldfallow <fi*********@gmail.com> wrote in news:dtmt1n$1g3$1
@emma.aioe.org:
I thought null pointers had a value of zero. Why is gcc's executable
printing ffffffffh?


http://c-faq.com/null/index.html

Sinan

Which part?

http://c-faq.com/null/nullor0.html

Clearly says that "C programmers must understand that NULL and 0 are
interchangeable in pointer contexts".

In addition:

"It is only in pointer contexts that NULL and 0 are equivalent"

Apart from his uninitiliased issues, his comments about null pointers
having a value of zero is fairly common isnt it?

--
Remove evomer to reply
Feb 24 '06 #18

P: n/a
"Richard G. Riley" <rg****@gmail.com> wrote:
On 2006-02-24, A. Sinan Unur <1u**@llenroc.ude.invalid> wrote:
fieldfallow <fi*********@gmail.com> wrote in news:dtmt1n$1g3$1
@emma.aioe.org:
I thought null pointers had a value of zero. Why is gcc's executable
printing ffffffffh?
http://c-faq.com/null/index.html


Which part?

http://c-faq.com/null/nullor0.html

Clearly says that "C programmers must understand that NULL and 0 are
interchangeable in pointer contexts".

In addition:

"It is only in pointer contexts that NULL and 0 are equivalent"


In code. Nowhere else. Not in memory; not in output. NULL is a null
pointer constant, _not_ a null pointer object. (And note that that
question does talk about what the programmer should use in his code, not
about anything else.)
Apart from his uninitiliased issues, his comments about null pointers
having a value of zero is fairly common isnt it?


Very common, but also wrong.

Richard
Feb 24 '06 #19

P: n/a
fieldfallow wrote:
At this point it seems to be an error in my implementation's printf()
regarding long doubles.
It does.
I'll writes some more demos and then try
reinstalling MinGW.

Thanks for your help.


You're welcome.

One reason that we obsess about undefined behavior in code here,
is that sometimes the effects are not where you expect to see them,
somewhat similarly to the way that the long double problem
affected the void pointer output.

I realise that this was not
a case of code containing undefined behavior,
but rather a case of it being the implementation's fault.

--
pete
Feb 24 '06 #20

P: n/a
Richard Bos wrote:
fieldfallow <fi*********@gmail.com> wrote:
Richard Tobin wrote:
In article <dt**********@emma.aioe.org>,
fieldfallow <fi*********@gmail.com> wrote:

> Accessing uninitialised values like that,
> causes undefined behavior in your program.
> The undefined behavior can show up in any part
> of the program's execution.
Does even printing out the values cause undefined behaviour?
Yes, but I would be surprised if it caused the behaviour shown.
Try removing the first printf and see if you still get the same
results for the second. Yes. Even after commenting out the first printf(), I still get the same
wrong output.


It does that for me, too[0]. When I remove the references to long
doubles in the printf(), it prints the expected[1] value for v_p, too.
It appears at first glance that gcc and the MinGW library are not in
accord over the size of a long double. How pernicious.

Try this: print (using sizeof) the size of your double and long double.


Output is:
sizeof (double) == 8
sizeof (long double) == 12
Dev-C++ on this computer says 8 and 12, respectively. But the headers
claim that long double is the same as double, and all values in
<float.h> for LDBL_* are the same as for DBL_*. Presumably, *printf()
assume that sizeof (double) == sizeof (long double), too.
Well, I use MinGW from the command line. The float.h in the main include
directory includes MS specific extensions and 'include_next' the ISO
float.h from 'lib/gcc/mingw32/3.4.5/include' directory. For me, the
relevant values are given as:
>>>>>>>

/* Maximum representable finite floating-point number,

(1 - b**-p) * b**emax
*/
#undef FLT_MAX
#undef DBL_MAX
#undef LDBL_MAX
#define FLT_MAX __FLT_MAX__
#define DBL_MAX __DBL_MAX__
#define LDBL_MAX __LDBL_MAX__

<<<<<<<<<<<<<
Anyone know the right channel to report this to MinGW?

Richard


There are probably mailing-lists for submitting bug reports on the MinGW
website.

Thanks for your help.

Feb 24 '06 #21

P: n/a
On 2006-02-24, Richard Bos <rl*@hoekstra-uitgeverij.nl> wrote:
"Richard G. Riley" <rg****@gmail.com> wrote:
On 2006-02-24, A. Sinan Unur <1u**@llenroc.ude.invalid> wrote:
> fieldfallow <fi*********@gmail.com> wrote in news:dtmt1n$1g3$1
> @emma.aioe.org:
>
>> I thought null pointers had a value of zero. Why is gcc's executable
>> printing ffffffffh?
>
> http://c-faq.com/null/index.html
Which part?

http://c-faq.com/null/nullor0.html

Clearly says that "C programmers must understand that NULL and 0 are
interchangeable in pointer contexts".

In addition:

"It is only in pointer contexts that NULL and 0 are equivalent"


In code. Nowhere else. Not in memory; not in output. NULL is a null
pointer constant, _not_ a null pointer object. (And note that that
question does talk about what the programmer should use in his code, not
about anything else.)
Apart from his uninitiliased issues, his comments about null pointers
having a value of zero is fairly common isnt it?


Very common, but also wrong.


Would you agree that a "null pointer" had a value of NULL? Possibly
I'm missing something here or giving the OP too much of the benefit of
the doubt.

Richard

Richard.

--
Remove evomer to reply
Feb 24 '06 #22

P: n/a
Richard G. Riley wrote:

On 2006-02-24, Richard Bos <rl*@hoekstra-uitgeverij.nl> wrote:
"Richard G. Riley" <rg****@gmail.com> wrote:
Apart from his uninitiliased issues,
his comments about null pointers
having a value of zero is fairly common isnt it?


Very common, but also wrong.


Would you agree that a "null pointer" had a value of NULL?


I wouldn't disagree.
I would say that a null pointer compares equal to NULL.
I would say that a null pointer compares equal to zero.

But these kinds of comparisons invlove conversions,
and when comparisons involve conversions,
then equivalence becomes context dependant.

if (0 > -1 && -1 > 0u && 0 == 0u) {
puts("If one constant compares greater than -1"
"and another compares less than -1,"
"can they have the same value?");
}

--
pete
Feb 24 '06 #23

P: n/a
On 2006-02-24, pete <pf*****@mindspring.com> wrote:
Richard G. Riley wrote:

On 2006-02-24, Richard Bos <rl*@hoekstra-uitgeverij.nl> wrote:
> "Richard G. Riley" <rg****@gmail.com> wrote: >> Apart from his uninitiliased issues,
>> his comments about null pointers
>> having a value of zero is fairly common isnt it?
>
> Very common, but also wrong.
>
Would you agree that a "null pointer" had a value of NULL?


I wouldn't disagree.
I would say that a null pointer compares equal to NULL.
I would say that a null pointer compares equal to zero.


And I would agree with your statements. In the same way I would say
that "1 compares equal to an int holding 1".

Does the compiler possibly cover up internal representations in these
cases too or do the standards limit it to pointers? Keeping in mind we
are talking C and not some higher level overloaded language.
But these kinds of comparisons invlove conversions,
and when comparisons involve conversions,
then equivalence becomes context dependant.

if (0 > -1 && -1 > 0u && 0 == 0u) {
puts("If one constant compares greater than -1"
"and another compares less than -1,"
"can they have the same value?");
}


http://c-faq.com/null/confusion4.html

... is a good description of how the NULL pointer might actually be
represented "out of code". The main issue, to my mind, is the
potential for a NULL pointer to hold a bit to raise HW
exceptions. Makes sense.

I assume the the compiler is smart enough to guess at ptr==NULL for
the following?

if(!ptr){
...
}

Or is that taking liberties?
Feb 24 '06 #24

P: n/a
"Richard G. Riley" <rg****@gmail.com> wrote in news:468k3hF9qhdjU3
@individual.net:
On 2006-02-24, A. Sinan Unur <1u**@llenroc.ude.invalid> wrote:
fieldfallow <fi*********@gmail.com> wrote in news:dtmt1n$1g3$1
@emma.aioe.org:
I thought null pointers had a value of zero. Why is gcc's executable
printing ffffffffh?


http://c-faq.com/null/index.html

Sinan

Which part?


Start from 5.1, continue until 5.20. The null pointer FAQs are organized
very well, starting with the definition, and answering each question in a
way that builds on the previous discussion.

Sinan
--
A. Sinan Unur <1u**@llenroc.ude.invalid>
(reverse each component and remove .invalid for email address)
Feb 24 '06 #25

P: n/a
Richard G. Riley wrote:
http://c-faq.com/null/confusion4.html

.. is a good description of how the NULL pointer might actually be
represented "out of code". The main issue, to my mind, is the
potential for a NULL pointer to hold a bit to raise HW
exceptions. Makes sense.

I assume the the compiler is smart enough to guess at ptr==NULL for
the following?
Yes.
if(!ptr){
..
}

Or is that taking liberties?


No.

(!(a)) means exactly the same thing as ((a) == 0)
no matter what type (a) is.

In a pointer context,
((ptr) == 0) means exactly the same thing as ((ptr) == NULL)

--
pete
Feb 24 '06 #26

P: n/a
On 2006-02-24, pete <pf*****@mindspring.com> wrote:
fieldfallow wrote:

pete wrote:
> fieldfallow wrote:
>> Hello all,
>>
>> Before stating my question,
>> I should mention that I'm fairly new to C.
>>
>> Now, I attempted a small demo that prints out
>> the values of C's numeric types, both uninitialised
>
> Accessing uninitialised values like that,
> causes undefined behavior in your program.
> The undefined behavior can show up in any part
> of the program's execution.


Does even printing out the values cause undefined behaviour?


Yes.
Is any
other operation legal, or must I assign them values before I do
anything with them?


For uninitialised objects,
you can only portably do operations which don't access the values.
That's pretty much limited to having the variables be
operands of the address operator and or the sizeof operator.


and the assignment operator.

and va_start() and va_copy() (macros which presumably invoke the
assignment operator)
Feb 24 '06 #27

P: n/a
On 2006-02-24, A. Sinan Unur <1u**@llenroc.ude.invalid> wrote:
"Richard G. Riley" <rg****@gmail.com> wrote in news:468k3hF9qhdjU3
@individual.net:
On 2006-02-24, A. Sinan Unur <1u**@llenroc.ude.invalid> wrote:
fieldfallow <fi*********@gmail.com> wrote in news:dtmt1n$1g3$1
@emma.aioe.org:

I thought null pointers had a value of zero. Why is gcc's executable
printing ffffffffh?

http://c-faq.com/null/index.html

Sinan

Which part?


Start from 5.1, continue until 5.20. The null pointer FAQs are organized
very well, starting with the definition, and answering each question in a
way that builds on the previous discussion.

Sinan

Firstly, I'm not trying to be purposefully counter productive
here. But I am confused as to your answer : especially when the OPs
problem was correctly disgnosed elsewhere as nothing to do with the
pointer value.

How would you disagree that the NULL pointer has a value of 0 for the
purposes of comparison and display? Which is what the OP asked and to
suggest he is wrong on this is a misleading thing in the context of
his problems isnt it?

It was very explicit that NULL and 0 are the same in the context of
pointers and comparisons. Note this is different to internal
representation as covered in other posts in the thread.

But anyhwere else that a NULL pointer is used in terms of being used
for mathematical manipulation of any time its value is 0.

Isn't it?

Have I tied myself up in knots here? Possibly.

--
Remove evomer to reply
Feb 24 '06 #28

P: n/a
On 2006-02-24, pete <pf*****@mindspring.com> wrote:
fieldfallow wrote:
At this point it seems to be an error in my implementation's printf()
regarding long doubles.


It does.
I'll writes some more demos and then try
reinstalling MinGW.

Thanks for your help.


You're welcome.

One reason that we obsess about undefined behavior in code here,
is that sometimes the effects are not where you expect to see them,
somewhat similarly to the way that the long double problem
affected the void pointer output.

I realise that this was not
a case of code containing undefined behavior,
but rather a case of it being the implementation's fault.


Probably in this case it's more mingw's fault than the printf
implementation's fault - for not using the same calling convention for
variadic functions [or perhaps any function at all] that take an
argument of long double type as windows natively uses. When using an
imlpementation built from pieces written by different groups of people,
and pieces which are themselves compiled on different implementations,
there is always a possibility of something like this.
Feb 24 '06 #29

P: n/a
Jordan Abel wrote:

On 2006-02-24, pete <pf*****@mindspring.com> wrote:
fieldfallow wrote:

pete wrote:
> fieldfallow wrote:
>> Hello all,
>>
>> Before stating my question,
>> I should mention that I'm fairly new to C.
>>
>> Now, I attempted a small demo that prints out
>> the values of C's numeric types, both uninitialised
>
> Accessing uninitialised values like that,
> causes undefined behavior in your program.
> The undefined behavior can show up in any part
> of the program's execution.

Does even printing out the values cause undefined behaviour?
Yes.
Is any
other operation legal, or must I assign them values before I do
anything with them?


For uninitialised objects,
you can only portably do operations which don't access the values.
That's pretty much limited to having the variables be
operands of the address operator and or the sizeof operator.


and the assignment operator.


.... as the left operand.
and va_start() and va_copy() (macros which presumably invoke the
assignment operator)


OK.

--
pete
Feb 24 '06 #30

P: n/a
On 2006-02-24, Richard G. Riley <rg****@gmail.com> wrote:
On 2006-02-24, A. Sinan Unur <1u**@llenroc.ude.invalid> wrote:
"Richard G. Riley" <rg****@gmail.com> wrote in news:468k3hF9qhdjU3
@individual.net:
On 2006-02-24, A. Sinan Unur <1u**@llenroc.ude.invalid> wrote:
fieldfallow <fi*********@gmail.com> wrote in news:dtmt1n$1g3$1
@emma.aioe.org:

> I thought null pointers had a value of zero. Why is gcc's executable
> printing ffffffffh?

http://c-faq.com/null/index.html

Sinan
Which part?
Start from 5.1, continue until 5.20. The null pointer FAQs are organized
very well, starting with the definition, and answering each question in a
way that builds on the previous discussion.

Sinan

Firstly, I'm not trying to be purposefully counter productive
here. But I am confused as to your answer : especially when the OPs
problem was correctly disgnosed elsewhere as nothing to do with the
pointer value.

How would you disagree that the NULL pointer has a value of 0 for the
purposes of comparison and display? Which is what the OP asked and to
suggest he is wrong on this is a misleading thing in the context of
his problems isnt it?

It might not for the purpose of display. Given that the _only_ thing
meaningful you can do with a pointer as far as 'display' is to print it
with the format specifier %p, the "value" of any pointer, including the
null pointer, for the purpose of display is an implementation-defined
string of characters.
It was very explicit that NULL and 0 are the same in the context of
pointers and comparisons. Note this is different to internal
representation as covered in other posts in the thread.

But anyhwere else that a NULL pointer is used in terms of being used
for mathematical manipulation of any time its value is 0.
You can't "mathematically manipulate" the null pointer. The only thing
you can do is compare it to another pointer. If you compare it to 0 or
to the macro NULL, that 0 is converted to a pointer before the
comparison.
Isn't it?

Have I tied myself up in knots here? Possibly.


"Comparisons" is superfluous here because the comparison causes 0 [or
the macro NULL, if it's not already a pointer] to be converted to a
pointer, just as an assignment would.
Feb 24 '06 #31

P: n/a
On 2006-02-24, Jordan Abel <ra*******@gmail.com> wrote:
On 2006-02-24, Richard G. Riley <rg****@gmail.com> wrote:
On 2006-02-24, A. Sinan Unur <1u**@llenroc.ude.invalid> wrote:
"Richard G. Riley" <rg****@gmail.com> wrote in news:468k3hF9qhdjU3
@individual.net:

On 2006-02-24, A. Sinan Unur <1u**@llenroc.ude.invalid> wrote:
> fieldfallow <fi*********@gmail.com> wrote in news:dtmt1n$1g3$1
> @emma.aioe.org:
>
>> I thought null pointers had a value of zero. Why is gcc's executable
>> printing ffffffffh?
>
> http://c-faq.com/null/index.html
>
> Sinan
Which part?

Start from 5.1, continue until 5.20. The null pointer FAQs are organized
very well, starting with the definition, and answering each question in a
way that builds on the previous discussion.

Sinan

Firstly, I'm not trying to be purposefully counter productive
here. But I am confused as to your answer : especially when the OPs
problem was correctly disgnosed elsewhere as nothing to do with the
pointer value.

How would you disagree that the NULL pointer has a value of 0 for the
purposes of comparison and display? Which is what the OP asked and to
suggest he is wrong on this is a misleading thing in the context of
his problems isnt it?

It might not for the purpose of display. Given that the _only_ thing
meaningful you can do with a pointer as far as 'display' is to print it
with the format specifier %p, the "value" of any pointer, including the
null pointer, for the purpose of display is an implementation-defined
string of characters.
It was very explicit that NULL and 0 are the same in the context of
pointers and comparisons. Note this is different to internal
representation as covered in other posts in the thread.

But anyhwere else that a NULL pointer is used in terms of being used
for mathematical manipulation of any time its value is 0.


You can't "mathematically manipulate" the null pointer. The only

thing

Sorry. Nomenclature. I (think) meant a pointer which is NULL. Or a
NULLed pointer : is this not a correct term? e.g.

ptr=NULL;

you can do is compare it to another pointer. If you compare it to 0 or
to the macro NULL, that 0 is converted to a pointer before the
comparison.
you mean if I

if(0==ptr)

then 0 is cast to a pointer of same type as ptr? I would expect that.

Hypothetical situation :

a char * which needs to point to memory address 0. What is the
thoughts on this? In this case the pointer must "hold 0" but is not
necessarily a NULL pointer?

I'm not *sure* I am disagreeing : maybe I'll print this out and go
through it again.

Isn't it?

Have I tied myself up in knots here? Possibly.


"Comparisons" is superfluous here because the comparison causes 0 [or
the macro NULL, if it's not already a pointer] to be converted to a
pointer, just as an assignment would.

--
Remove evomer to reply
Feb 24 '06 #32

P: n/a
On 2006-02-24, Richard G. Riley <rg****@gmail.com> wrote:
On 2006-02-24, Jordan Abel <ra*******@gmail.com> wrote:
On 2006-02-24, Richard G. Riley <rg****@gmail.com> wrote:
On 2006-02-24, A. Sinan Unur <1u**@llenroc.ude.invalid> wrote:
"Richard G. Riley" <rg****@gmail.com> wrote in news:468k3hF9qhdjU3
@individual.net:

> On 2006-02-24, A. Sinan Unur <1u**@llenroc.ude.invalid> wrote:
>> fieldfallow <fi*********@gmail.com> wrote in news:dtmt1n$1g3$1
>> @emma.aioe.org:
>>
>>> I thought null pointers had a value of zero. Why is gcc's executable
>>> printing ffffffffh?
>>
>> http://c-faq.com/null/index.html
>>
>> Sinan
>
>
> Which part?

Start from 5.1, continue until 5.20. The null pointer FAQs are organized
very well, starting with the definition, and answering each question in a
way that builds on the previous discussion.

Sinan
Firstly, I'm not trying to be purposefully counter productive
here. But I am confused as to your answer : especially when the OPs
problem was correctly disgnosed elsewhere as nothing to do with the
pointer value.

How would you disagree that the NULL pointer has a value of 0 for the
purposes of comparison and display? Which is what the OP asked and to
suggest he is wrong on this is a misleading thing in the context of
his problems isnt it?

It might not for the purpose of display. Given that the _only_ thing
meaningful you can do with a pointer as far as 'display' is to print it
with the format specifier %p, the "value" of any pointer, including the
null pointer, for the purpose of display is an implementation-defined
string of characters.
It was very explicit that NULL and 0 are the same in the context of
pointers and comparisons. Note this is different to internal
representation as covered in other posts in the thread.

But anyhwere else that a NULL pointer is used in terms of being used
for mathematical manipulation of any time its value is 0.


You can't "mathematically manipulate" the null pointer. The only

thing

Sorry. Nomenclature. I (think) meant a pointer which is NULL. Or a
NULLed pointer : is this not a correct term? e.g.

ptr=NULL;


I'd say "null pointer" - "NULL pointer" is not technically correct, but
i knew what you meant. How do you think you can "mathematically
manipulate" it? multiply or divide it by something? take its logarithm
base 10?
you can do is compare it to another pointer. If you compare it to 0 or
to the macro NULL, that 0 is converted to a pointer before the
comparison.


you mean if I

if(0==ptr)

then 0 is cast to a pointer of same type as ptr? I would expect that.

Hypothetical situation :

a char * which needs to point to memory address 0. What is the
thoughts on this? In this case the pointer must "hold 0" but is not
necessarily a NULL pointer?


Conversion of an integer (i.e. an integer that is not a constant
expression equal to 0) to a pointer is implementation-defined.

If you really needed this, an implementation would probably go about it
by having the internal representation of a null pointer be some other
value, and you'd do (char *)(int)0 [with the cast to int to make the 0
no longer be a null pointer constant].
Feb 24 '06 #33

P: n/a
fieldfallow a écrit :
Where is the mistake?


You are just kidding, aren't you ?

Compiling: main.c
main.c: In function `main_':
main.c:6: warning: 'c' might be used uninitialized in this function
main.c:7: warning: 'uc' might be used uninitialized in this function
main.c:8: warning: 's' might be used uninitialized in this function
main.c:9: warning: 'us' might be used uninitialized in this function
main.c:10: warning: 'i' might be used uninitialized in this function
main.c:11: warning: 'ui' might be used uninitialized in this function
main.c:12: warning: 'l' might be used uninitialized in this function
main.c:13: warning: 'ul' might be used uninitialized in this function
main.c:14: warning: 'f' might be used uninitialized in this function
main.c:15: warning: 'd' might be used uninitialized in this function
main.c:16: warning: 'ld' might be used uninitialized in this function
main.c:17: warning: 'v_p' might be used uninitialized in this function

--
C is a sharp tool
Feb 24 '06 #34

P: n/a
fieldfallow a écrit :
Where is the mistake?


You are just kidding, aren't you ?

Compiling: main.c
main.c: In function `main_':
main.c:6: warning: 'c' might be used uninitialized in this function
main.c:7: warning: 'uc' might be used uninitialized in this function
main.c:8: warning: 's' might be used uninitialized in this function
main.c:9: warning: 'us' might be used uninitialized in this function
main.c:10: warning: 'i' might be used uninitialized in this function
main.c:11: warning: 'ui' might be used uninitialized in this function
main.c:12: warning: 'l' might be used uninitialized in this function
main.c:13: warning: 'ul' might be used uninitialized in this function
main.c:14: warning: 'f' might be used uninitialized in this function
main.c:15: warning: 'd' might be used uninitialized in this function
main.c:16: warning: 'ld' might be used uninitialized in this function
main.c:17: warning: 'v_p' might be used uninitialized in this function

I'm no sure long double is supported by my implementation. (Code::Blocks)

This code

#include <stdio.h>
#include <limits.h>
#include <float.h>

#define LONG_DOUBLE 0

int main(void)
{
char c=CHAR_MIN;
unsigned char uc=0;
short s=SHRT_MIN;
unsigned short us=0;
int i=INT_MIN;
unsigned int ui=0;
long l=LONG_MIN;
unsigned long ul=0;
float f=FLT_EPSILON;
double d=DBL_EPSILON;
long double ld=LDBL_EPSILON;
void *v_p=0;

printf(" c = '%c' or %d\n"
" uc = '%c' or %u\n"
" s = %hd\n"
" us = %hu\n"
" i = %d\n"
" ui = %u\n"
" l = %ld\n"
" ul = %lu\n"
" f = %f or %g\n"
" d = %f or %g\n"
#if LONG_DOUBLE
" ld = %Lf or %Lg\n"
#endif
"v_p = %p\n"
, (int) c
, (int) c
, (int) uc
, (unsigned) uc
, (short) s
, (unsigned short) us
, (int) i
, (unsigned) ui
, (long) l
, (unsigned long) ul
, (double) f
, (double) f
, (double) d
, (double) d
#if LONG_DOUBLE
, (long double) ld
, (long double) ld
#endif
, (void*) v_p);

puts("Initialising them with their maximum allowed values...");
c = CHAR_MAX;
uc = UCHAR_MAX;
s = SHRT_MAX;
us = USHRT_MAX;
i = INT_MAX;
ui = UINT_MAX;
l = LONG_MAX;
ul = ULONG_MAX;
f = FLT_MAX;
d = DBL_MAX;
ld = LDBL_MAX;
puts("Initialising v_p with NULL...");
v_p = NULL;

printf(" c = '%c' or %d\n"
" uc = '%c' or %u\n"
" s = %hd\n"
" us = %hu\n"
" i = %d\n"
" ui = %u\n"
" l = %ld\n"
" ul = %lu\n"
" f = %f or %g\n"
" d = %f or %g\n"
#if LONG_DOUBLE
" ld = %Lf or %Lg\n"
#endif
"v_p = %p\n"
, (int) c
, (int) c
, (int) uc
, (unsigned) uc
, (short) s
, (unsigned short) us
, (int) i
, (unsigned) ui
, (long) l
, (unsigned long) ul
, (double) f
, (double) f
, (double) d
, (double) d
#if LONG_DOUBLE
, (long double) ld
, (long double) ld
#endif
, (void*) v_p);

return 0;
}
Sounds correct to me:

c = 'Ç' or -128
uc = ' ' or 0
s = -32768
us = 0
i = -2147483648
ui = 0
l = -2147483648
ul = 0
f = 0.000000 or 1.19209e-007
d = 0.000000 or 2.22045e-016
v_p = 00000000
Initialising them with their maximum allowed values...
Initialising v_p with NULL...
c = '?' or 127
uc = ' ' or 255
s = 32767
us = 65535
i = 2147483647
ui = 4294967295
l = 2147483647
ul = 4294967295
f = 340282346638528860000000000000000000000.000000 or 3.40282e+038
d =
17976931348623157000000000000000000000000000000000 000000000000000000000000
00000000000000000000000000000000000000000000000000 000000000000000000000000000000
00000000000000000000000000000000000000000000000000 000000000000000000000000000000
00000000000000000000000000000000000000000000000000 0000000000000000000000000.0000
00 or 1.79769e+308
v_p = 00000000
--
C is a sharp tool
Feb 24 '06 #35

P: n/a
Emmanuel Delahaye wrote:
fieldfallow a écrit :
Where is the mistake?


You are just kidding, aren't you ?

Compiling: main.c
main.c: In function `main_':
main.c:6: warning: 'c' might be used uninitialized in this function
main.c:7: warning: 'uc' might be used uninitialized in this function
main.c:8: warning: 's' might be used uninitialized in this function
main.c:9: warning: 'us' might be used uninitialized in this function
main.c:10: warning: 'i' might be used uninitialized in this function
main.c:11: warning: 'ui' might be used uninitialized in this function
main.c:12: warning: 'l' might be used uninitialized in this function
main.c:13: warning: 'ul' might be used uninitialized in this function
main.c:14: warning: 'f' might be used uninitialized in this function
main.c:15: warning: 'd' might be used uninitialized in this function
main.c:16: warning: 'ld' might be used uninitialized in this function
main.c:17: warning: 'v_p' might be used uninitialized in this function


Yes. It was soon pointed out to me by others the danger of using
uninitialised variables. However, it was later found that there is a
long double and printf() related bug in my implementation (gcc 3.4.5 and
MinGW 5.0.0).

This turned out to be the actual cause of incorrect output, even though
it could have just as well been the accessing of the uninitialised
variables.

Thanks.
Feb 24 '06 #36

P: n/a
"Richard G. Riley" <rg****@gmail.com> writes:
On 2006-02-24, A. Sinan Unur <1u**@llenroc.ude.invalid> wrote:
fieldfallow <fi*********@gmail.com> wrote in news:dtmt1n$1g3$1
@emma.aioe.org:
I thought null pointers had a value of zero. Why is gcc's executable
printing ffffffffh?


http://c-faq.com/null/index.html

Sinan

Which part?

http://c-faq.com/null/nullor0.html

Clearly says that "C programmers must understand that NULL and 0 are
interchangeable in pointer contexts".

In addition:

"It is only in pointer contexts that NULL and 0 are equivalent"


NULL may even be #defined as 0.

The difference is, that, assuming a 16-bit integer type with no
padding bits,

int foo = 0;

is guaranteed to give foo an all-zeroed-bits representation, whereas

void *bar = 0;

is not. Again, assuming the same conditions above about integer types,
you could do:

int *baz = calloc(sizeof *baz);

and *baz would be guaranteed to have the value zero (but don't use
code like the above, because in general you /can't/ make these
assumptions about padding bits, etc). But

void **quux = calloc(sizeof *quux);

is /not/ guaranteed to make *quux a NULL pointer, or compare equal to
zero.

The short: null pointers must be comparable to zero, but need not be
represented like zero. 0xFFFFFFFF is perfectly reasonable (though,
unlikely on his particular implementation AFAIK).

HTH,
-Micah
Feb 24 '06 #37

P: n/a
Jordan Abel <ra*******@gmail.com> writes:
On 2006-02-24, Richard G. Riley <rg****@gmail.com> wrote:
a char * which needs to point to memory address 0. What is the
thoughts on this? In this case the pointer must "hold 0" but is not
necessarily a NULL pointer?


Conversion of an integer (i.e. an integer that is not a constant
expression equal to 0) to a pointer is implementation-defined.

If you really needed this, an implementation would probably go about it
by having the internal representation of a null pointer be some other
value, and you'd do (char *)(int)0 [with the cast to int to make the 0
no longer be a null pointer constant].


This last bit is wrong. It's still an integer constant expression with
the value 0: it still must result in a null pointer.

However:

int foo = 0;
char *bar = foo;

might work. Since it's implementation defined, who knows?

-Micah
Feb 24 '06 #38

P: n/a
"Richard G. Riley" <rg****@gmail.com> wrote in
news:46************@individual.net:
On 2006-02-24, A. Sinan Unur <1u**@llenroc.ude.invalid> wrote:
"Richard G. Riley" <rg****@gmail.com> wrote in news:468k3hF9qhdjU3
@individual.net:
On 2006-02-24, A. Sinan Unur <1u**@llenroc.ude.invalid> wrote:
fieldfallow <fi*********@gmail.com> wrote in news:dtmt1n$1g3$1
@emma.aioe.org:

> I thought null pointers had a value of zero. Why is gcc's
> executable printing ffffffffh?

http://c-faq.com/null/index.html

Sinan
Which part?
Start from 5.1, continue until 5.20. The null pointer FAQs are
organized very well, starting with the definition, and answering each
question in a way that builds on the previous discussion.

.... Firstly, I'm not trying to be purposefully counter productive
here. But I am confused as to your answer : especially when the OPs
problem was correctly disgnosed elsewhere as nothing to do with the
pointer value.
OK, I have had time to read the rest of the thread, and I understand the
bug.

The only point I was trying to make was that there is no reason to
expect that printing a null pointer value will yield any specific string
to be emitted.
How would you disagree that the NULL pointer has a value of 0 for the
purposes of comparison and display?


Comparison, yes.

Sinan
--
A. Sinan Unur <1u**@llenroc.ude.invalid>
(reverse each component and remove .invalid for email address)
Feb 24 '06 #39

P: n/a
On 2006-02-24, Micah Cowan <mi***@cowan.name> wrote:
Jordan Abel <ra*******@gmail.com> writes:
On 2006-02-24, Richard G. Riley <rg****@gmail.com> wrote:
> a char * which needs to point to memory address 0. What is the
> thoughts on this? In this case the pointer must "hold 0" but is not
> necessarily a NULL pointer?
Conversion of an integer (i.e. an integer that is not a constant
expression equal to 0) to a pointer is implementation-defined.

If you really needed this, an implementation would probably go about it
by having the internal representation of a null pointer be some other
value, and you'd do (char *)(int)0 [with the cast to int to make the 0
no longer be a null pointer constant].


This last bit is wrong. It's still an integer constant expression with
the value 0: it still must result in a null pointer.


Casts are not, as far as I can tell, part of constant-expression.
However:

int foo = 0;
char *bar = foo;

might work. Since it's implementation defined, who knows?

-Micah

Feb 24 '06 #40

P: n/a
Jordan Abel wrote:
Casts are not, as far as I can tell, part of constant-expression.


Why not?

The only thing that every expression has, is a type.
If the type of a constant expression comes from a cast,
then the cast sure seems like part of the expression to me.

--
pete
Feb 24 '06 #41

P: n/a
On 2006-02-24, pete <pf*****@mindspring.com> wrote:
Jordan Abel wrote:
Casts are not, as far as I can tell, part of constant-expression.


Why not?

The only thing that every expression has, is a type.
If the type of a constant expression comes from a cast,
then the cast sure seems like part of the expression to me.


but constant-expression is the argument to #if - and casts can't be
evaluated by the preprocessor
Feb 24 '06 #42

P: n/a
Jordan Abel <ra*******@gmail.com> writes:
On 2006-02-24, pete <pf*****@mindspring.com> wrote:
Jordan Abel wrote:
Casts are not, as far as I can tell, part of constant-expression.


Why not?

The only thing that every expression has, is a type.
If the type of a constant expression comes from a cast,
then the cast sure seems like part of the expression to me.


but constant-expression is the argument to #if - and casts can't be
evaluated by the preprocessor


There seems to be some confusion here between what the
context-free grammar for the constant-expression nonterminal can
produce and what is actually allowed in a constant expression.
The CFG for constant-expression is very liberal:

1 constant-expression:
conditional-expression

However, the constraints on constant-expression are more
restrictive than the CFG.
--
"...deficient support can be a virtue.
It keeps the amateurs off."
--Bjarne Stroustrup
Feb 24 '06 #43

P: n/a
Jordan Abel wrote:

On 2006-02-24, pete <pf*****@mindspring.com> wrote:
Jordan Abel wrote:
Casts are not, as far as I can tell, part of constant-expression.


Why not?

The only thing that every expression has, is a type.
If the type of a constant expression comes from a cast,
then the cast sure seems like part of the expression to me.


but constant-expression is the argument to #if - and casts can't be
evaluated by the preprocessor


That's a different issue that has to do with
the illiteracy of the preproccessor.

The result of the sizeof operator is a constant expression.
You can declare an array with it in C89.
char array[sizeof(int)];
But you can't use sizeof with #if either.

N869
6.6 Constant expressions
[#8]
Cast operators
in an arithmetic constant expression shall only convert
arithmetic types to arithmetic types, except as part of an
operand to the sizeof operator.

--
pete
Feb 24 '06 #44

P: n/a
Ben Pfaff <bl*@cs.stanford.edu> writes:
Jordan Abel <ra*******@gmail.com> writes:
On 2006-02-24, pete <pf*****@mindspring.com> wrote:
Jordan Abel wrote:

Casts are not, as far as I can tell, part of constant-expression.

Why not?

The only thing that every expression has, is a type.
If the type of a constant expression comes from a cast,
then the cast sure seems like part of the expression to me.


but constant-expression is the argument to #if - and casts can't be
evaluated by the preprocessor


There seems to be some confusion here between what the
context-free grammar for the constant-expression nonterminal can
produce and what is actually allowed in a constant expression.
The CFG for constant-expression is very liberal:

1 constant-expression:
conditional-expression

However, the constraints on constant-expression are more
restrictive than the CFG.


And yet still allow casts (even for "integer constant expressions",
which are the most constrained, and are in fact what we're talking about).

As to casts being evaluated by the preprocessor; that is a
_special_exception_ for the preprocessor.

-Micah
Feb 24 '06 #45

P: n/a
"Micah Cowan" <mi***@cowan.name> wrote in message
news:87************@mcowan.barracudanetworks.com.. .
NULL may even be #defined as 0.

The difference is, that, assuming a 16-bit integer type with no
padding bits,
I think you do not need the assumption of no padding bits. The Standard
quotes:
"For any integer type, the object representation where all the bits
are zero shall be a representation of the value zero in that type."
There is no distinction between padding and value bits.
int foo = 0;

is guaranteed to give foo an all-zeroed-bits representation, whereas

void *bar = 0;

is not. Again, assuming the same conditions above about integer types,
you could do:

int *baz = calloc(sizeof *baz);

and *baz would be guaranteed to have the value zero (but don't use
code like the above, because in general you /can't/ make these
assumptions about padding bits, etc).
That same assumption is redundant here as well. Of course, i agree with all
the rest.
But

void **quux = calloc(sizeof *quux);

is /not/ guaranteed to make *quux a NULL pointer, or compare equal to
zero.

The short: null pointers must be comparable to zero, but need not be
represented like zero. 0xFFFFFFFF is perfectly reasonable (though,
unlikely on his particular implementation AFAIK).

Feb 24 '06 #46

P: n/a
On 2006-02-24, stathis gotsis <st***********@hotmail.com> wrote:
"Micah Cowan" <mi***@cowan.name> wrote in message
news:87************@mcowan.barracudanetworks.com.. .
NULL may even be #defined as 0.

The difference is, that, assuming a 16-bit integer type with no
padding bits,


I think you do not need the assumption of no padding bits. The Standard
quotes:
"For any integer type, the object representation where all the bits
are zero shall be a representation of the value zero in that type."
There is no distinction between padding and value bits.


That holds in one direction, but it could be that assigning zero to the
variable will result in padding bits set to 1.
Feb 25 '06 #47

P: n/a
fieldfallow wrote:
...
I thought null pointers had a value of zero. Why is gcc's executable
printing ffffffffh? Also the value of 'ld' seems to be wrong.
...


No. A null pointer has value correctly referred to as... well, 'null
pointer value' (NPV). This value can have any physical representation
chosen by implementation: it could be all zeros, it could be 0xFFFFFFFF,
it could be 0xBAADFOOD or anything else. It could also be type-specific,
i.e. different pointer types can use different physical representations
of their NPV.

What is normally meant by "null pointers had a value of zero" is that
constant integral value '0', when used in pointer context, is
automatically interpreted as NPV of the corresponding type (i.e. it is
implicitly replaced with the correct physical representation of the NPV
by the compiler).

For example, if in some implementation value of 0xBAADFOOD is used as
physical representation of NPV or type 'int*' and value 0xFFFFFFFF is
used as physical representation of NPV or type 'double*', the C code

int* pi = 0;
double* pd = 0;

will be translated into a sequence of operations that physically
initialize 'pi' with value 0xBAADFOOD and 'pd' with value of 0xFFFFFFFF.

--
Best regards,
Andrey Tarasevich
Feb 25 '06 #48

P: n/a

"Jordan Abel" <ra*******@gmail.com> wrote in message
news:sl***********************@random.yi.org...
On 2006-02-24, stathis gotsis <st***********@hotmail.com> wrote:
"Micah Cowan" <mi***@cowan.name> wrote in message
news:87************@mcowan.barracudanetworks.com.. .
NULL may even be #defined as 0.

The difference is, that, assuming a 16-bit integer type with no
padding bits,


I think you do not need the assumption of no padding bits. The Standard
quotes:
"For any integer type, the object representation where all the bits
are zero shall be a representation of the value zero in that type."
There is no distinction between padding and value bits.


That holds in one direction, but it could be that assigning zero to the
variable will result in padding bits set to 1.


I missed that one. What i said applies in this situation:

int *baz = calloc(sizeof *baz);

where *baz = 0.
Feb 25 '06 #49

P: n/a
"stathis gotsis" <st***********@hotmail.com> writes:
"Micah Cowan" <mi***@cowan.name> wrote in message
news:87************@mcowan.barracudanetworks.com.. .
NULL may even be #defined as 0.

The difference is, that, assuming a 16-bit integer type with no
padding bits,


I think you do not need the assumption of no padding bits. The Standard
quotes:
"For any integer type, the object representation where all the bits
are zero shall be a representation of the value zero in that type."
There is no distinction between padding and value bits.


Mm, quite. I'd forgotten about TC2.
Feb 25 '06 #50

69 Replies

This discussion thread is closed

Replies have been disabled for this discussion.