Difference between runtime and syntax error [duplicate] - c

This question already has answers here:
Is not using & with a variable in scanf() a syntax error or a runtime error?
(2 answers)
Closed 7 years ago.
I have a problem like this:
Q. Pick ANY error you can have from here:
int main(void)
{
int a;
printf("Input a integer number >>");
scanf("%d\n", a);
printf("The input number is %d\n", a);
return 0;
}
syntax error
logical error
run-time error
no error
I thought it was both syntax and run-time error because:
For syntax, there is no & in front of a.
For run-time error, the program would still be built to run the first print statement and suddenly stop at scanf() statement because there is no &.
However, I was told that I'm wrong.
I know that it is not logical error, but I'm confused which one is which.

Syntax errors are detected by compiler. This program compiles fine, so it does not have syntax errors.
However, this program passes the value of an uninitialized variable a to scanf, which is undefined behavior, i.e. a runtime error.

No, there will not be any syntax error here, only run-time error.
scanf() expects a pointer to the variable to store the value but that does not mandate that we have to use the & operator always to pass an address.
Imagine, in case a would have been a pointer (and allocated proper memory),
scanf("%d\n", a);
would have been a perfectly valid statement, isn't it?
In this code, you have passed the value of an uninitialized variable (which get tread as an address, which will be invalid) as an argument to the %d format specifier to scanf(), so that invokes undefined behavior that causes runtime error.

Related

How the printf function works in c when format specifier is not correct? [duplicate]

This question already has answers here:
How printf works in case of type mismatch with type specifier?
(3 answers)
Closed 5 years ago.
In an Interview, I was asked the output of the following code snippet:
printf("%d", "computer");
I am a c# developer and earlier I had learned C too, but when this question was asked, I had no clue.
When I run the same question in windows 10 computer (64-bit), it is giving putput as
3571712
Please give reasons why this is happening.
It doesn't "work", what you observe is an outcome of undefined behavior.
Quoting C11, chapter §7.21.6.1/p9
[...] If any argument is
not the correct type for the corresponding conversion specification, the behavior is
undefined.
In your case, the conversion specifier is %d which expects an argument of type int but you're supplying a char*, and they are not the compatible type, hence the UB.
well value of "computer" is memory address where that string is stored. It could be value of that address is: 3571712 (But you should not rely on this - see below).
But to print memory address void* you should use %p format specifier. And using incorrect format specifiers is undefined behavior.
In an Interview, I was asked the output of the following code snippet [...]
Your answer could have been:
a. "This is undefined behavior"
b. "A number will most likely be printed, but I cannot tell you which number because I do not know where the string is stored, as the string's address will be attempted to be interpreted as an integer by the printf function".
c. "Which platform? Which compiler?"
It will not work it's giving the garbage value of these variables. And the main reason is that we use "%d" for the output of int not for string.

Why compiler is not issuing error while passing an int (not int *) as the argument of scanf()?

I tried the below c program & I expected to get compile time error, but why compiler isn't giving any error?
#include <stdio.h>
#include <conio.h>
int main()
{
int a,b;
printf("Enter a : ");
scanf("%d",&a);
printf("Enter b : ");
scanf("%d",b);
printf("a is %d and b is %d\n",a,b);
getch();
return 0;
}
I am not writing & in scanf("%d",b). At the compile time , compiler don't give any error but during execution value of b is 2686792(garbage value).
As per C11 standard, Chapter §6.3.2.3
An integer may be converted to any pointer type. Except as previously specified, the
result is implementation-defined, might not be correctly aligned, might not point to an
entity of the referenced type, and might be a trap representation.
So, the compiler will allow this, but the result is implementation-defined.
In this particular case, you're passing b to scanf() as an argument, which is uninitialized, which will cause the program to invoke undefined behaviour, once executed.
Also, printf() / scanf() being variadic functions, no check on paramater type is perforfmed in general, unless asked explicitly through compiler flag [See -Wformat].
It is not a a compile time error but a runtime issue.
The compiler expects that you have given a valid address to scan the value to, during runtime only it will come to know whether the address is valid or not .
If you try to scan the value to invalid address it leads to undefined behavior and might see a crash.
It scans fine because scanf expects a memory location in its argument. That's why we use & to give memory location of the corresponding variable.
In your case scanf just scans the entered value and puts it in the memory location which has the value of b(instead of scanning and putting it in the memory location where b is stored).
The & operator in C returns the address of the operand. If you give just the b without the & operator, it will be passed by value and the scanf won't be able to set the value. This would result in unexpected behaviour as you already noticed. It has no way of verifying the address before the runtime and hence you won't notice the issue until runtime.

Why does this C program crash? It compiled fine [duplicate]

This question already has an answer here:
Program crashes when trying to read numbers with scanf
(1 answer)
Closed 8 years ago.
This program compiles fine. When I input a number, it crashes on me. name.exe has stopped working But why?
int main (void) {
int arrayMax = 0;
printf ("How many numbers will be entered?\n");
scanf ("%i", arrayMax);
int i;
double userInput [arrayMax];
return 0;
}
scanf ("%i", &arrayMax);
Do this scan to the address using &. You need to pass the address of the variable to which you need to scan the value to. In this case your variable is arrayMax and you need to pass the address of this variable which the scanf() expects and in this case you are not doing so and passing 0 which is not the memory location to which you want to scan your value to so you see crash.
Writing to in-valid memory location causes crash.
You forget to place & operator in the scanf argument.
scanf ("%i", &arrayMax);
// ^Place unary & to specify the location.
scanf is a variadic function.
As such, the compiler cannot determine whether or not the type of each argument passed to it is correct (expect for the type of the first argument, which is explicitly declared as const char*).
As a result, the decision is "moved" from compile-time to run-time, and so instead of a compile-time error you might get a run-time error.
For example, in the case of scanf("%i"), the function expects the address of an int variable.
In your code you are passing the value 0, so scanf will first scan user-input, and then attempt to write it at that memory address.
If the memory segment which includes this address does not have Write access permission (for example, if the code-section of your program resides at that address), then this attempt will result with a memory access violation during runtime.
You can get it to work correctly by changing scanf("%i",arrayMax) to scanf("%i",&arrayMax).

The output of the following C program should be 3, but I am getting 0 why? [duplicate]

This question already has answers here:
Wrong output from printf of a number
(8 answers)
Closed 8 years ago.
main()
{
printf ("%d",(3.0/2)*2) ;
}
The output of the following C program should be 3. Why am I getting 0?
The directive %d expects an integer (of type int), but you're passing a floating-point value (of type double).
Depending on the compiler, the processor, the exact content of the program, and the phase of the moon, this could do anything (it's undefined behavior): crash, print some bogus value, make daemons fly out of your nose… Here, it happens that the compiler generates code that fetches an integer value from somewhere which happens to contain the value 0 at that point.
To print the floating-point value, change the printf directive:
int main(void)
{
printf ("%f", (3.0/2)*2);
}
To print an integer, convert the argument with a cast:
int main(void)
{
printf ("%d", (int)((3.0/2)*2));
}
Good compilers warn you when you make such mistakes. Make sure to turn up your compiler's warning level.
Change 3.0/2 to 3.0/2.0
printf("%d",(int)((3.0/2.0)*2));

Please explain this ambiguity in C

When I am compiling this program I am getting some random number as output.. In Cygwin the output is 47 but in RHEL5, it is giving some negative random numbers as output.
Can anyone tell me the reason?
Code:
main()
{
printf("%d");
}
This program provokes undefined behavior since it does not follow the rules of C. You should give printf one argument per format specifier after the format string.
On common C implementations, it prints whatever happens to be on the stack after the pointer to "%d", interpreted as an integer. On others, it may send demons flying out of your nose.
It is Undefined Behaviour.
On 3 counts:
absence of prototype for a function taking a variable number of arguments
lying to printf by telling it you are sending 1 argument and sending none
absence to return a value from main (in C99 a return 0; is assumed, but your code definitely isn't C99)
Anything can happen.
printf expects a second argument, so it reads whatever happens to be on the stack at that location. Essentially it's reading random memory and printing it out.

Resources