Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can it cause problems to pass the address to an array instead of the array?

Tags:

arrays

c

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?

like image 742
klutt Avatar asked Nov 25 '18 21:11

klutt


People also ask

Can array be passed by address?

In each case, the array is passed by reference/address to the function.

Why is not possible to pass an array to a 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.

Can you change the address pointed to by an array variable?

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.

Why are arrays passed by address?

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.


2 Answers

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.

like image 126
M.M Avatar answered Nov 05 '22 11:11

M.M


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.

like image 25
Paul Avatar answered Nov 05 '22 12:11

Paul