1

I have used a very simple code:

int main(void)
{
    size_t variable;
    /*prompt*/
    printf("enter the value of the variable: ");
    scanf("%zd", variable);
    printf("you entered %zd value of the variable", variable);
}  

Howeve, the GCC compiler produces the following result:

Enter the vale of the size_t variable: 15
You entered zd value of size_t type
Process returned 35 (0X23)  execution time: 3.094s
Press any key to continue

My book also demonstrates the above example directly without mentioning that it is some kind of a special format specifier if library files were to be included. Even the online compiler is not producing correct results. Why is the code not working?

chux - Reinstate Monica
  • 143,097
  • 13
  • 135
  • 256
bzal
  • 201
  • 2
  • 9
  • Because you called `printf` without passing the argument for the specifier. – StoryTeller - Unslander Monica Feb 21 '17 at 09:17
  • If you turned on more warnings, you'd see that you passed the *value* of `variable` instead of its *address* to `scanf()`. – Toby Speight Feb 21 '17 at 09:19
  • 1
    Possible duplicate of [How to use "zd" specifier with \`printf()\`?](http://stackoverflow.com/questions/32916575/how-to-use-zd-specifier-with-printf) – Jayesh Feb 21 '17 at 09:20
  • `"%zd"` is expects a matching `signed size_t` argument, but in your case `size_t variable;` is `long unsigned int`. What are you trying there? – Michi Feb 21 '17 at 09:21
  • 3
    Chapter 1 of any beginner-level programming book should explain how to use these functions. You must also figure out how to enable compiler warnings. – Lundin Feb 21 '17 at 09:22
  • @Lundin, it was a typing error, I'm sorry – bzal Feb 21 '17 at 10:48

2 Answers2

6
scanf("%zd", variable);

Is undefined behavior because you didn't pass a pointer.

printf("you entered %zd value of the variable");

Is also undefined behavior because you used a format specifier but didn't pass a matching argument.

%zd is a mandatory feature of a hosted implementation of C11. Meaning it is mandatory for any compiler that implements stdio.h. However, %zd doesn't make much sense since size_t is always unsigned. Use %zu instead.

Please note that non-compliant implementations of the standard library exists, most notably Microsoft's implementation for Windows. The Microsoft implementation of the standard library is used by Visual Studio and also by the gcc/mingw compiler. This library does not support %zu properly since it does not follow the C11 standard.

Lundin
  • 195,001
  • 40
  • 254
  • 396
2

Nopes, %zd is one of the required format specifiers for an implementation to be conforming, it's not optional.

Quoting C11, chapter §7.21.6.2, fscanf()

z Specifies that a following d, i, o, u, x, X, or n conversion specifier applies to an argument with type pointer to size_t or the corresponding signed integer type.

That said, in your code, the usage is wrong, for two reasons.

  1. You need to pass a pointer-to-type as the argument for the supplied conversion specifier.
  2. size_t is defined to be of unsigned integer type, so you should use the appropriate format specifier, %zu, not %zd.

    Quoting C11 again, chapter §7.19

    size_t

    which is the unsigned integer type of the result of the sizeof operator;

Something like

 scanf("%zu", &variable);

should work fine.

Sourav Ghosh
  • 133,132
  • 16
  • 183
  • 261