Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why is it possible to pass a double pointer (address of address) to scanf?

Tags:

c

scanf

This simple code is what I would expect:

#include <stdio.h>

int main()
{
    char input[20];
    printf("enter a string: ");
    scanf("%[^\n]s", input);
    printf("input: %s\n", input);
}

where input is (char*)[20]. But then why can I pass this:

#include <stdio.h>

int main()
{
    char input[20];
    printf("enter a string: ");
    scanf("%[^\n]s", &input);
    printf("input: %s\n", input);
}

and it still compiles and runs? The argument &input passed should be (char**)[20] which should not be correct, yet it runs. Why?

like image 860
milanHrabos Avatar asked Mar 02 '23 20:03

milanHrabos


1 Answers

In your code, the expression input (when used as an argument to scanf) will evaluate (i.e. decay) to the address of the first element of the 20-character array and the expression &input will evaluate to the address of the array itself - which will be the same, in this case. This can be demonstrated by adding a line like the following to your code:

    printf("%p %p\n", (void*)(input), (void*)(&input)); // Print the two addresses - SAME!

Thus, your call to scanf will actually pass the correct value (the address of the input buffer).

However, a good compiler will warn you about the incompatible pointer type; for example, clang-cl generates this:

warning : format specifies type 'char *' but the argument has type
'char (*)[20]' [-Wformat]

It is, of course, up to you whether you want to address the warning or ignore it; but, in more complex code, such 'mistakes' can cause run-time errors that are very difficult to track down.

like image 127
Adrian Mole Avatar answered Apr 27 '23 15:04

Adrian Mole