简体   繁体   中英

(Q. is little wrong So please check body) C float *q=NULL; printf(“%f”,q) ; output is 0.000000 but in C++ float *q=nullptr; cout<<q; give output 0?

[My Question is little weird but it's not right to change it now as it is answered with good explanation but I am Editing it with [Update].......[Update End] tag to avoid confusion to upcoming visitors to my post]

C

#include<stdio.h>
int main()
{
    float *q=NULL;
    
    printf("%f\n",q);
}

OUTPUT

0.000000
  • In C output is 0.000000
  • so here q is float type null pointer or still q is (void *) type null pointer?
  • I feel it is (void *) type.
  • so mismatch in format(%f) and argument(void*) invoke undefined behaviour and lead to such error type output

[Update] But you will fill answer to my own Question such stupid Question I asked

basically I am confused that I feel I have to print something float type or void type but point is I am printing address and so it just foolish to use %f to use to print address.

Obviously q is float type pointer only what I feel is totally wrong

generally we use %u to print address of any type of variable(int,char,float) but for pointer we should use %p

[Update End]

C++

#include<iostream>
int main()
{
    float *q=nullptr;
    std::cout<<q;
}

OUTPUT

0
  • In C++ give output 0
  • I think it's fine as it give address of 1st memory block as pointing to nothing
  • and if q is nullptr_t type then C++11 should give ambugity error means here q is float type nullptr.

[Update]

The C and C++ standards both specify that a null pointer constant compares equal to zero - they say nothing about what is at that address.

obviously q is float type nullptr only

[Update End]

So if my both assumptions are correct then why in C++ nullptr changing it's type to float type from nullptr_t but in C NULL is not changing it's type from (void ) to (float ) ?

[Update]

My first assumption in 1st example of C that q is (void*) type is already wrong and 2nd Assumption that in 2nd ex. of C++ that q is nullptr_t is also wrong.

So Summarize all here

I am trying to compare that this is happening in C and this is happening in c++ and I feel these things are contradict to each other

but in reality while in C I am using %f to print address of pointer that's first mistake. In C++ code all I think is all right except One thing that it is wrong to assume that null pointer points to 1st block of memory which is 0th as it is not specify in c standard it just say that nullptr constant compares to 0 when evaluate.

so tons of mistake in question only so it is not proper question

[Update End]

 printf("%f\n",q);

The format specifier %f requires that the type of the passed object is of type double ( float argument will be converted implicitly, so that is OK too). You passed a float* which is the wrong type. Passing argument of wrong type into printf results in undefined behaviour.

 printf("%p",q);

This one is a bit more subtle, but %p specifier requires the type of the argument to be void* . float* is still the wrong type, so behaviour is still undefined.

You should be more careful about using the correct format specifier and type of argument. The C formatted I/O API is very unforgiving.


In C++ give output 0

Note that whether you get output of 0 or something else depends on what value the system uses to represent the null pointer.

why in C++ nullptr changing it's type to float type from nullptr_t

nullptr never "changed its type to float type" in your example. In float *q=nullptr , the implicit conversion is to the type float* .

but in C NULL is not changing it's type from (void ) to (float)?

Type of the NULL macro is not void in C. It can be an integer constant 0, or such constant converted to void* . Both of those could be implicitly converted to any pointer type. That's what happens in float *q=NULL .

So, in both languages you implicitly converted null to a pointer type.


Regardless of what types can be implicitly converted to which types, variadic arguments are not implicitly converted to the types required by the format string because those types are unknown to the compiler 1 2 .

1 There are conversions such as from float to double that I mentioned, but those are not dependent on the format specifiers.

2 If the format string is constant, some compilers do helpfully diagnose your mistakes, but they aren't required to do so.

The pointer isn't changing type. In the cout version, you're letting the system print the pointer value natural. In the printf version you're forcing a %f. Change the format string to %ld and you'll get different results.

printf doesn't know a thing about what you're passing as arguments. It trusts the programmer knows what he's doing.

--- Edit here to answer more questions ---

You're right that %lu is probably better than %ld. I suppose it's possible that you'd have an address with the most significant bit set (which would mean %ld would think it's negative).

Yes:

float * q = nullptr;

Means q is all-zero.

Cout knows what is being printed and (usually) does the right thing. It is rare to use format specifiers unless you're very specifically controlling it (like number of digits to use when printing out floats & doubles). I use it to set default output of bools to print true or false instead of 1 or 0 . But generally speaking, you get sane values when using cout without any extra work or thought necessary.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM