Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p>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 <code>char(*)[100]</code>. 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.</p> <p>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 <code>char*</code> and pass that to printf.</p> <p>So, <strong>never do it with <code>&amp;a</code></strong> and pass it to scanf using "%s". Good compilers, as comeau, will warn you correctly:</p> <blockquote> <p>warning: argument is incompatible with corresponding format string conversion</p> </blockquote> <p>Of course, the <code>&amp;a</code> and <code>(char*)a</code> <em>have</em> the same address stored. But that does not mean you can use <code>&amp;a</code> and <code>(char*)a</code> interchangeably.</p> <hr> <p>Some Standard quotes to especially show how pointer arguments are <em>not</em> converted to <code>void*</code> auto-magically, and how the whole thing is undefined behavior. </p> <blockquote> <p>Except when it is the operand of the sizeof operator or the unary &amp; operator, or is a string literal used to initialize an array, an expression that has type <em>‘‘array of type’’ is converted</em> to an expression with type <em>‘‘pointer to type’’</em> that points to the initial element of the array object. (<code>6.3.2.1/3</code>)</p> </blockquote> <p>So, that is done always - it isn't mentioned below explicitly anymore when listening valid cases when types may differ.</p> <blockquote> <p>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. (<code>6.5.2.2/7</code>)</p> </blockquote> <p>About how <code>va_arg</code> behaves extracting the arguments passed to printf, which is a vararg function, emphasis added by me (<code>7.15.1.1/2</code>):</p> <blockquote> <p>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 <code>*</code> 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 <em>behavior is undefined</em>, except for the following cases: </p> <ul> <li>one type is a signed integer type, the other type is the corresponding unsigned integer type, and the value is representable in both types;</li> <li>one type is <em>pointer to void</em> and the other is a pointer to a <em>character type</em>.</li> </ul> </blockquote> <p>Well, here is what that <em>default argument promotion</em> is:</p> <blockquote> <p>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. (<code>6.5.2.2/6</code>)</p> </blockquote>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload