[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 compiler1 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.
As an experiment:
I have hypothetical function with signature: void func(void *), where I have to pass an integer value, literally in the code: func(42). It must be done with a literal integer.
Is there a “right” way to pass a integer value, say, “hacked” as an address in a pointer (to address 0x2A for example), and the somehow convert it back to an integer (42 for the 0x2A example). All of this without unexpected behavior?
In short: being able to convert a pointer address into an integer which will hold the number of the address.
Both C and C++ standards explicitly allow for such conversion.
C99 6.3.2.3.5:
An integer may be converted to any pointer type. Except as previously specified, the
result is implementation-defined, might not be correctly aligned, might not point to an
entity of the referenced type, and might be a trap representation.
C++11 5.2.10.5
A value of integral type or enumeration type can be explicitly converted to a pointer.
Therefore, your call of func((void*)42) should work with all standard-compliant compilers.
What is the, say, most correct way to pass a literal integer to an argument expecting a void pointer, and having the integer untouched in the function?
This way of passing a literal integer as an argument to a function expecting a void* guarantees that the original integer would be untouched in the function, because the argument is passed by value.
It shouldn't be done this way.
You can allocate the value on the stack and then call the function.
Example in C:
int i = 42;
func((void*) (&i));
Example in C++:
int i = 42;
func(reinterpret_cast<void*> (&i));
Otherwise, if you are not sure about the life time of the variable, it can be allocated on the heap using malloc()/free() or new/delete.
So recently I've been dealing with WinAPI's WriteProcessMemory and ReadProcessMemory which both take LPVOID as their second argument which is the actual address in the memory of another process we want to read from.
Considering that, would this integer to pointer conversion be correct C++ code (without undefined behavior, etc.):
#include <windows.h>
int main()
{
WriteProcessMemory(/*...*/,
//want to read from memory address 0x1234 in the target process
reinterpret_cast<void*>(static_cast<uintptr_t>(0x1234)),
/*...*/);
return 0;
}
AFAIK, the standard says that uintptr_t is an integer type which is able to hold a pointer without the value of the pointer being changed. Since it is an integer, I should be able to store 0x1234 in it. The standard also says that reinterpret_casting an uintptr_t to a void* will also leave the value unchanged.
On Windows platforms the pointer is stored exactly in the same way as the same bit-count integer type. The difference is how the compiler interpretes the value of a pointer and an int. So no conversion is neccessary.
Casting it to void */LPVOID is just to make the compiler happy and accept the integer value in a place for pointer and no conversion is made. Going through static_cast+reinterpret_cast is overkill in this case.
As long as you are sure that the correct address is 0x1234, conversion is not needed. Just a plain (LPVOID)0x1234 or (void *)0x1234 should do.
[edit] As noted in the comments the constant may get truncated. Then no conversion can fix the pointer value. A way to handle this is to explicitly specify the type used in the constant:
E.g. (void *)0x1234567812345678ULL will be OK because the compiler is instructed to use 64bit unsigned type.
The following expression is used in C to get the address of a particular element.
&a[x]
What is the type of the value returned? What is this dependent on? Is it always the same by convenetion or is it dependent on the operating system?
I need to know this because:
I need to extract a bit pattern from within this pointer so Im trying to understand whether the value is hex or binary. When you say a pointer is it like: 0x25434 or like 0111000111?
Becuase that would affect how I extract my bits
For an array of T, the type of the returned value is pointer-to-T, declared as T *:
T a[] = ...;
T *ptr = &a[n];
How this pointer is displayed—in binary, hex, decimal, Morse—is entirely up to the code displaying it. The %p format value is a popular choice for debugging, and it will typically print the pointer's value (the memory address) in hexadecimal.
If the address the pointer points to needs to be expressed as a number, it can be obtained by casting the pointer to the uintptr_t integral type:
uintptr_t addr = (uintptr_t) ptr;
The bits of the address can then be inspected with the usual arithmetic and binary operators.
if a[] is array of int, it will be int*, for example.
If you new to C language, i would recommend you read this book http://en.wikipedia.org/wiki/The_C_Programming_Language
I recently embarrassed myself while explaining to a colleague why
char a[100];
scanf("%s", &a); // notice a & in front of 'a'
is very bad and that the slightly better way to do it is:
char a[100];
scanf("%s", a); // notice no & in front of 'a'
Ok. For everybody getting ready to tell me why scanf should not be used anyway for security reasons: ease up. This question is actually about the meaning of "&a" vs "a".
The thing is, after I explained why it shouldn't work, we tried it (with gcc) and it works =)). I ran a quick
printf("%p %p", a, &a);
and it prints the same address twice.
Can anybody explain to me what's going on?
Well, the &a case should be obvious. You take the address of the array, exactly as expected.
a is a bit more subtle, but the answer is that a is the array. And as any C programmer knows, arrays have a tendency to degenerate into a pointer at the slightest provocation, for example when passing it as a function parameter.
So scanf("%s", a) expects a pointer, not an array, so the array degenerates into a pointer to the first element of the array.
Of course scanf("%s", &a) works too, because that's explicitly the address of the array.
Edit: Oops, looks like I totally failed to consider what argument types scanf actually expects. Both cases yield a pointer to the same address, but of different types. (pointer to char, versus pointer to array of chars).
And I'll gladly admit I don't know enough about the semantics for ellipsis (...), which I've always avoided like the plague, so looks like the conversion to whichever type scanf ends up using may be undefined behavior. Read the comments, and litb's answer. You can usually trust him to get this stuff right. ;)
Well, scanf expects a char* pointer as the next argument when seeing a "%s". But what you give it is a pointer to a char[100]. You give it a char(*)[100]. It's not guaranteed to work at all, because the compiler may use a different representation for array pointers of course. If you turn on warnings for gcc, you will see also the proper warning displayed.
When you provide an argument object that is an argument not having a listed parameter in the function (so, as in the case for scanf when has the vararg style "..." arguments after the format string), the array will degenerate to a pointer to its first element. That is, the compiler will create a char* and pass that to printf.
So, never do it with &a and pass it to scanf using "%s". Good compilers, as comeau, will warn you correctly:
warning: argument is incompatible with corresponding format string conversion
Of course, the &a and (char*)a have the same address stored. But that does not mean you can use &a and (char*)a interchangeably.
Some Standard quotes to especially show how pointer arguments are not converted to void* auto-magically, and how the whole thing is undefined behavior.
Except when it is the operand of the sizeof operator or the unary & operator, or is a
string literal used to initialize an array, an expression that has type ‘‘array of type’’ is converted to an expression with type ‘‘pointer to type’’ that points to the initial element of the array object. (6.3.2.1/3)
So, that is done always - it isn't mentioned below explicitly anymore when listening valid cases when types may differ.
The ellipsis notation in a function prototype declarator causes argument type conversion to stop after the last declared parameter. The default argument promotions are performed on trailing arguments. (6.5.2.2/7)
About how va_arg behaves extracting the arguments passed to printf, which is a vararg function, emphasis added by me (7.15.1.1/2):
Each invocation of the va_arg macro modifies ap so that the
values of successive arguments are returned in turn. The parameter type shall be a type
name specified such that the type of a pointer to an object that has the specified type can be obtained simply by postfixing a * to type. If there is no actual next argument, or if type is not compatible with the type of the actual next argument (as promoted according to the default argument promotions), the behavior is undefined, except for the following cases:
one type is a signed integer type, the other type is the corresponding unsigned integer
type, and the value is representable in both types;
one type is pointer to void and the other is a pointer to a character type.
Well, here is what that default argument promotion is:
If the expression that denotes the called function has a type that does not include a
prototype, the integer promotions are performed on each argument, and arguments that
have type float are promoted to double. These are called the default argument
promotions. (6.5.2.2/6)
It's been a while since I programmed in C but here's my 2c:
char a[100] doesn't allocate a separate variable for the address of the array, so the memory allocation looks like this:
---+-----+---
...|0..99|...
---+-----+---
^
a == &a
For comparison, if the array was malloc'd then there is a separate variable for the pointer, and a != &a.
char *a;
a = malloc(100);
In this case the memory looks like this:
---+---+---+-----+---
...| a |...|0..99|...
---+---+---+-----+---
^ ^
&a != a
K&R 2nd Ed. p.99 describes it fairly well:
The correspondence between indexing
and pointer arithmetic is very close.
By definition, the value of a variable
or expression of type array is the
address of element zero of the array.
Thus after the assignment pa=&a[0];
pa and a have identical values. Since
the name of the array is a synonym for
the location of the initial element,
the assignment pa=&a[0] can also be
written as pa=a;
A C array can be implicitly converted to a pointer to its first element (C99:TC3 6.3.2.1 §3), ie there are a lot of cases where a (which has type char [100]) will behave the same way as &a[0] (which has type char *). This explains why passing a as argument will work.
But don't start thinking this will always be the case: There are important differences between arrays and pointers, eg regarding assignment, sizeof and whatever else I can't think of right now...
&a is actually one of these pitfalls: This will create a pointer to the array, ie it has type char (*) [100] (and not char **). This means &a and &a[0] will point to the same memory location, but will have different types.
As far as I know, there is no implicit conversion between these types and they are not guaranteed to have a compatible representation as well. All I could find is C99:TC3 6.2.5 §27, which doesn't says much about pointers to arrays:
[...] Pointers to other types need not have the same representation or alignment requirements.
But there's also 6.3.2.3 §7:
[...] When a pointer to an object is converted to a pointer to a character type, the result points to the lowest addressed byte of the object. Successive increments of the result, up to the size of the object, yield pointers to the remaining bytes of the object.
So the cast (char *)&a should work as expected. Actually, I'm assuming here that the lowest addressed byte of an array will be the lowest addressed byte of its first element - not sure if this is guaranteed, or if a compiler is free to add arbitrary padding in front of an array, but if so, that would be seriously weird...
Anyway for this to work, &a still has to be cast to char * (or void * - the standard guarantees that these types have compatible representations). The problem is that there won't be any conversions applied to variable arguments aside from the default argument promotion, ie you have to do the cast explicitly yourself.
To summarize:
&a is of type char (*) [100], which might have a different bit-representation than char *. Therefore, an explicit cast must be done by the programmer, because for variable arguments, the compiler can't know to what it should convert the value. This means only the default argument promotion will be done, which, as litb pointed out, does not include a conversion to void *. It follows that:
scanf("%s", a); - good
scanf("%s", &a); - bad
scanf("%s", (char *)&a); - should be ok
Sorry, a tiny bit off topic:
This reminded me of an article I read about 8 years ago when I was coding C full time. I can't find the article but I think it was titled "arrays are not pointers" or something like that. Anyway, I did come across this C arrays and pointers FAQ which is interesting reading.
char [100] is a complex type of 100 adjacent char's, whose sizeof equals to 100.
Being casted to a pointer ((void*) a), this variable yields the address of the first char.
Reference to the variable of this type (&a) yields address of the whole variable, which, in turn, also happens to be the address of the first char