I ran into this code:
char str[600];
scanf("%s", &str);
Of course, this emits this warning:
a.c:6:17: warning: format specifies type 'char *' but the argument has type
'char (*)[600]' [-Wformat]
scanf("%s", &str);
~~ ^~~~~~~
I know that the correct way is to remove the &
and type scanf("%s", str)
instead. But it does work, so my question is if this could cause any problems. Is it undefined behavior? When I switched str
to a pointer instead of an array it (obviously) did not work. But can this cause any problem when using an array?
In each case, the array is passed by reference/address to the function.
The reason you can't pass an array by value is because there is no specific way to track an array's size such that the function invocation logic would know how much memory to allocate and what to copy. You can pass a class instance because classes have constructors.
You cannot swap the address of array elements. The array elements are all stored in sequence in memory. If an integer takes 4 bytes in memory, for an array of size 10, a total of 40 contiguous bytes are taken in memory.
An array passed into a function is always passed by address, since the array's name IS a variable that stores its address (i.e. a pointer). Pass-by-address can be done in returns as well -- we can return the address of an array.
Yes, the code is undefined behaviour. The argument corresponding to %s
must have the type char *
. This is described in C17 7.21.6.2/12 under the s
specifier:
[...] the corresponding argument shall be a pointer to the initial element of a character array large enough to accept the sequence and a terminating null character, which will be added automatically.
which says fairly clearly that the pointer should have pointer-to-character type, and not point to the whole array.
Undefined behaviour means that anything can happen. It might behave as if you omitted the &
, or it might format your hard drive.
Given that it is extremely easy to avoid undefined behaviour in this case, I don't really see any reason to engage in arguments about whether it is OK to rely on the behaviour of undefined behaviour in this situation.
Using &str
instead of str
didn't cause any problems in this case because the addresses of those two are the same. See this past question for an explanation. But as you note, the type of &str
is different, and the compiler throws up a warning, and the actual behavior will depend on architecture and implementation.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With