What will be the output of printf("%d"); or printf("%p"); statement?
Of course I know that I should pass argument as printf is expecting one but assuming that I will leave this empty what will happen?
I know that this will print some value read from stack (from the place where function argument should be placed). Assuming that I am running Linux machine can I expect that this will be some valid value (e.g. function return address)?
This is simply undefined behaviour. Anything could happen. It's impossible to give a more accurate answer.
The details depend on how printf is implemented by the library, and how variable arguments are implemented by your compiler. Look at the source of the library and/or the generated assembly to find out what's happening on your platform.
This invokes undefined behavior. By its very nature, this means you can't assume anything about what will happen.
This provokes undefinded behaviour. You might get printed out a random integer or a crash or ...
Undefined behavior. Which means your program can for example crash.
(C99, 7.19.6.1p2) "If there are insufficient arguments for the format, the behavior is
undefined."
can I expect that this will be some valid value? : NO.
Related
I try to rewrite printf function and i found a strange result when use format specifier (%) with ! or K. I want to understand why i get this result.
printf("%!");
printf("%K")
I get output ! and K.
Thank for all response
According to §7.21.6.1 ¶9 of the ISO C11 standard, using an invalid conversion specification will result in undefined behavior.
Therefore, you cannot rely on any specific behavior. Anything may happen. On different compilers, the behavior may be different. Even on the same compiler the behavior may change, if you for example update the compiler to a different version or compile with a different optimization level.
If you want the behavior to be well-defined, so that you can rely on a specific behavior, then you should only use valid conversion specifiers. You can use the %% conversion specification to print a literal %.
printf("%!"); printf("%K") are both undefined behavior. Any result is possible.
As part of OP's rewrite, code can do anything in these cases.
What if we just give format string in printf statement in c like:
printf("%d, %d, %d",a, b);
What does the third %d give In answer?
I did it but not able to understand the output of the code.
The third %d gives in answer undefined behavior because there is no corresponding argument.
From the C Standard (7.21.6.1 The fprintf function)
9 If a conversion specification is invalid, the behavior is
undefined.275) If any argument is not the correct type for the
corresponding conversion specification, the behavior is undefined.
Pay attention to that the name of the standard function is printf not Printf.
In C, functions that take variadic arguments (i.e. the ... parameter) have no way of knowing beforehand the number or type of the arguments. They must be kept track of in some way. A separate length parameter is one way, but the printf-family functions use the number of format specifiers in the format string to keep track.
If you tell the function "hey, there's a third parameter" when you don't pass one, this is undefined behavior. Anything can happen. It may appear to not print anything. It may read a garbage value from the memory location or the register where it expects to find the value. It may crash.
Reasoning about what might happen when your code invokes undefined behavior is a waste of time. Just make sure your code is free of it.
You've told printf to expect 3 additional int arguments, but only passed 2. It's going to look for that third int argument somewhere, and depending on how printf is implemented on your system, you may get a runtime error, or you may see garbage output, or you may see no output, or something entirely different may happen.
Officially, the behavior is left undefined - neither the compiler nor the runtime environment the program is executing in are required to handle the situation in any particular way. The result isn't guaranteed to be predictable or repeatable.
There is no "should" here - any result is "correct" as far as the language definition is concerned.
This question already has answers here:
Checking return value of a function without return statement
(3 answers)
Closed 8 years ago.
So, I did some changes in this simple program for understanding purposes.
Here is the code:
#include<stdio.h>
add1(int a,int b){
int j = a + b; // Statement-1
int y = a - b; // Statement-2
}
void main() {
int result = add1(5,7);
printf("%d",result);
}
I know that the default return type of a C function is int and the default return value is return 0 if the function is main, else the return value is undefined if the function does return something. I know that it is not a good practice. But here are my observations:
The return value of add1 takes the value of the closest declared variable to the ending brace of the add1 function i.e in my code y. Hence, the output is -2. If I comment the statement-2 the output becomes 12.
So, is this what we call undefined behavior?
Yes. Once there is undefined behavior, result may comes out to be either expected or unexpected.
C faq - 11.33:
undefined: Anything at all can happen; the Standard imposes no requirements. The program may fail to compile, or it may execute incorrectly (either crashing or silently generating incorrect results), or it may fortuitously do exactly what the programmer intended.
C faq - 11.35:
A compiler may do anything it likes when faced with undefined behavior (and, within limits, with implementation-defined and unspecified behavior), including doing what you expect. It's unwise to depend on it, though.
Yes. §6.9.1 ¶12 of N1256 (C99) states:
If the } that terminates a function is reached, and the value of the function call is used by the caller, the behavior is undefined.
It appears that you are saying that your compiler appears to return the value of the last defined variable and are wondering whether that particular algorithm is what is meant by "undefined behavior." Actually the algorithm that a particular compiler uses, if any, to set a return value, in a way, doesn't really demonstrate notion of undefined behavior.
The right way to look at things is that the language specification allows a (conforming) compiler to generate code that does whatever it wants to set a return value (or crash or go into an infinite loop).
The fact that you appeared to have found that your compiler does some particular thing is actually somewhat irrelevant. It didn't have to do what you found it to do. It could have done something else.
Not that anyone asked, but what you are seeing is probably a result of what generally happens in C compilers: the value returned from a function is the value that happens to be held in a particular processor register when the function exits. It appears your compiler is targeting its computations directly into that special register. So yeah, the fact that you are seeing what you are seeing makes sense (at least to compiler writers).
But it doesn't have to be that way. The fact that it is that way simply agrees with the language requirement of undefined behavior, but it is not "what is meant by" undefined behavior.
Maybe this is just a nit-pick, but it reflects how I read the question.
A question was asked in a multiple choice test: What will be the output of the following program:
#include <stdio.h>
int main(void)
{
int a = 10, b = 5, c = 2;
printf("%d %d %d\n");
return 0;
}
and the choices were various permutations of 10, 5, and 2. For some reason, it works in Turbo C++, which we use in college. However, it doesn't when compiled with gcc (which gives a warning when -Wall is enabled) or clang (which has -Wformat enabled and gives a warning by default) or in Visual C++. The output is, as expected, garbage values. My guess is that it has something to do with the fact that either Turbo C++ is 16-bit, and running on 32-bit Windows XP, or that TCC is terrible when it comes to standards.
The code has undefined behaviour.
In Turbo C++, it just so happens that the three variables live at the exact positions on the stack where the missing printf() argument would be. This results in the undefined behaviour manifesting itself by having the "correct" values printed.
However, you can't reasonably rely on this to be the case. Even the slightest change to your build environment (e.g. different compiler options) could break things in an arbitrarily nasty way.
The answer here is that the program could do anything -- this is undefined behavior. According to printf()s documentation (emphasis mine):
By default, the arguments are used in the order given, where each '*' and each conversion specifier asks for the next argument (and it is an error if insufficiently many arguments are given).
If your multiple-choice test does not have a choice for "undefined behavior" then it is a flawed test. Under the influence of undefined behavior, any answer on such a multiple-choice test question is technically correct.
It is an undefined behaviour. So it could be anything.
Try to use
printf("%d %d%d", a,b,c)
Reason:- Local variables are called on the stack and printf in Turbo C++ sees them in the same order in which they were assigned in the stack.
SUGGESTION(From comments):-
Understanding why it behaves in a particular way with a particular compiler can be useful in diagnosing problems, but don't make any other use of the information.
What's actually going on is that arguments are normally passed on the call stack. Local variables are also passed on the call stack, and so printf() sees those values, in whatever order the compiler decided to store them there.
This behavior, as well as many others, are allowed under the umbrella of undefined behavoir
No, it's not related to architecture. It is related to how TurboC++ handles the stack. Variables a, b, and c are locals and as such allocated in the stack. printf also expects the values in the stack. Apparently, TurboC++ does not add anything else to the stack after the locals and printf is able to take them as parameters. Just coincidence.
Is there anything you could supply to the atoi function that would produce an error (that may or may not crash the program)?
EDIT: An error is defined as anything that would produce a compilation error, or something that would cause the program to terminate during execution.
anything that would produce a compilation error
If the argument you supply to atoi() is of an incompatible type, you'll get a compile-time error.
something that would cause the program to terminate during execution
If you supply atoi() with an invalid const char* pointer, the behaviour of your code will be undefined. While nothing is guaranteed, if the pointer is NULL or points to unreadable memory the program will likely terminate (this depends on the OS and the hardware architecture).
I suspect the question is more along the lines of 'do I have to sanitize the input from a source I dont trust before passing it to atoi?'
The behavior of a correctly written atoi function is specified for most cases. It will convert characters to numbers until it hits something non numeric and then stop. However atoi is considered vulnerable to overflows
You should use strtol instead; its spec is tighter
Of course the implementation in your c runtime could be broken - but then there is not a lot you can do about that