Reputation: 21
Why the value of the input
variable is set to zero if I pass incorrectly ordered type specifier for id
variable?
#include <stdio.h>
#include <stdlib.h>
#include<string.h>
#define MAX 100
int main()
{
int i=0;
int input;
char *name=(char *)malloc(sizeof(char)*MAX);
unsigned short int id;
printf("\nPlease enter input:\t");
scanf("%d", &input);
getchar();//to take \n
printf("\nEnter name.....\n");
fgets(name,MAX,stdin);
printf("\nEnter id: ");
scanf("%uh",&id);//type specifier should have been %hu
printf("%d",input);//value set to 0?
}
Why is input
being overridden by scanf("%uh", &id)
?
Upvotes: 0
Views: 215
Reputation: 51815
EDIT (After re-reading question/comments):
Mentat has nailed the problem! I'll leave some fragments of my original answer, with some additions ...
(1) The warning about using %uh
should be accepted at face value: to input a short
integer (signed or unsigned), you need the h
modifier before the type specifier (u
or d
) - that's just the way scanf
format specifiers work.
(2) Your code happens to work on MSVC
, so I missed the point. With clang-cl
I found your error: As the h
size modifier is being ignored, the value read in by '%uh' is a (long or 32-bit) unsigned
, which is being written to memory that you've allocated as a short
(16-bit) unsigned
. As it happens, that variable (id
)is in memory next to input
, so part of input is being overwritten by the high 16-bits of the 32-bit unsigned you are writing to id
.
(3) Try entering a value of 65537 for your first input and then the value will still be modified (probably to 65536), but not cleared to zero.
(4) Recommend: Accept and upvote the answer from Mentat. Feel free to downvote my answer!
Yours, humbly!
Upvotes: 0
Reputation: 381
Jyoti Rawat
You have what I call a memory over run error. Microsoft (Visual Studio) calls it:
"Stack around the variable ‘id’ was corrupted"
Not all computer systems treat memory over runs errors the same. Visual Studio/Windows catch this error and throw an exception.
OpenVMS would just execute the instruction and then continue on to the next instruction. In either case, if the program continues, its behavior will be undefined.
In English, you are writing more bits of data into a variable that cannot contain it. The extra bits are written to other memory locations not assigned to the variable. As mention by chux, statements that follow will have undefined behavior.
Solution:
As you already know and mention by others, change the format specifier from "uh" to "hu".
Things to note about your code:
Upvotes: 2
Reputation: 153338
Why the value of the input variable is set to zero if I pass incorrectly ordered type specifier to id variable?
unsigned short int id;
scanf("%uh",&id);//type specifier should have been %hu
scanf()
first uses "%u"
and looks for a matching unsigned *
argument. As code passed a unsigned short *
the result is undefined behavior (UB).
The result of 0 is not demo'd with printf("%d",input);
. Perhaps OP meant printf("%d",id);
?
In any case, code after the UB of scanf()
is irrelevant. It might print 0
today or crash the code tomorrow - it is UB.
Upvotes: 0