It works without stdio.h !!

  • Thread starter karthikbalaguru
  • Start date
K

karthikbalaguru

Hi ,

I find that the below program works without the inclusion
of the stanard input/output library.
I understand that we mandatorily need a valid prototype in scope for
functions like printf to avoid undefined behaviour and
that can be done through #include <stdio.h> only.
But, the below code runs perfectly well without those
statment. Strange !!

int main(void)
{
int a = 1,b;
char t[10];
printf(a ?"one \n" : "zero \n") ;
scanf("%d",&b);
printf("b = %d \n",b);
strcpy(t,"Hello");
printf("%s \n",t);
return 0;
}

It works without the famous #include<stdio.h> .
Strange ? How is it possible ?

I use Visual C++ 2008 express edition for C compilation
and debugging.

Any ideas ?

Thx in advans,
Karthik Balaguru
 
J

James Kuyper

karthikbalaguru said:
Hi ,

I find that the below program works without the inclusion
of the stanard input/output library.

Incorrect - it works without inclusion of the standard header. There's a
big difference. Most compilers automatically link to the standard
I understand that we mandatorily need a valid prototype in scope for
functions like printf to avoid undefined behaviour and
that can be done through #include <stdio.h> only.

Incorrect. In C99 a diagnostic message is required if there is no
declaration in scope when a function is called. However, it does not
have to be a prototyped declaration; it's still permitted to use a K&R
style declaration. After issuing the diagnostic, an implementation is
free to continue compilation and linking. The resulting program has
undefined behavior, which means that it's behavior is not constrained in
any way by the C standard, but it might just do exactly what you expect
it to do, whatever that might be. The standard gives you no
justification for expecting any particular kind of behavior for such a
program).

However, if you're using a C90 compiler, no diagnostic is required. If a
function is called with no declaration in scope, in C90 it was
implicitly declared as a function returning an 'int' with an unspecified
but fixed number of arguments of unspecified types. If the function
actually does return a type compatible with 'int', and the promoted type
of each argument happens to be compatible with the type expected by the
function being called, the function call will actually work.

This can never be true for printf() or scanf(), which are variadic
functions, rather than functions with a fixed number of arguments, so
your program has undefined behavior. However, on many systems variadic
functions are implemented in ways that would allow it to actually work
as expected. That's one permitted form or undefined behavior.
But, the below code runs perfectly well without those
statment. Strange !!

int main(void)
{
int a = 1,b;
char t[10];

This definition leaves 't' uninitialized.
printf(a ?"one \n" : "zero \n") ;
scanf("%d",&b);
printf("b = %d \n",b);
strcpy(t,"Hello");

You're using the contents of 't' before they've been initialized. As a
result, the behavior of this program would still be undefined even if
you #included <stdio.h>. If this program happens to work as expected,
that's pure dumb luck. However, I know of at least one system where
automatic variables that are not explicitly initialized are
zero-initialized by default, even though the standard only requires such
behavior for static variables. That might be why your program "worked".
 
W

Willem

James Kuyper wrote:
) karthikbalaguru wrote:
)> int main(void)
)> {
)> int a = 1,b;
)> char t[10];
)
) This definition leaves 't' uninitialized.

Yes, and ? It gets initialized below

)> printf(a ?"one \n" : "zero \n") ;
)> scanf("%d",&b);
)> printf("b = %d \n",b);
)> strcpy(t,"Hello");

't' gets a value here. I don't see the problem.

) You're using the contents of 't' before they've been initialized.

Huh ? How ? The first use of 't' is writing to it, no ?


SaSW, Willem
--
Disclaimer: I am in no way responsible for any of the statements
made in the above text. For all I know I might be
drugged or something..
No I'm not paranoid. You all think I'm paranoid, don't you !
#EOT
 
J

James Kuyper

Willem said:
James Kuyper wrote:
) karthikbalaguru wrote:
)> int main(void)
)> {
)> int a = 1,b;
)> char t[10];
)
) This definition leaves 't' uninitialized.

Yes, and ? It gets initialized below

)> printf(a ?"one \n" : "zero \n") ;
)> scanf("%d",&b);
)> printf("b = %d \n",b);
)> strcpy(t,"Hello");

't' gets a value here. I don't see the problem.

) You're using the contents of 't' before they've been initialized.

Huh ? How ? The first use of 't' is writing to it, no ?

Sorry, for some reason I was thinking strcat() rather than strcpy().
Please pretend I never said anything that stupid. :)
 
K

karthikbalaguru

Incorrect - it works without inclusion of the standard header. There's a
big difference. Most compilers automatically link to the standard
library (except for the parts declared in <math.h>), whether or not you
#include the relevant standard headers.

Does gcc support that functionality ?

Thx in advans,
Karthik Balaguru
 
K

Kenny McCormack

Does gcc support that functionality ?

Be careful. James is playing games with you over what is meant by "the
standard library". He is jerking you around, pretending not to
understand what you mean by the term.
 
B

Barry Schwarz

Hi ,

I find that the below program works without the inclusion
of the stanard input/output library.
I understand that we mandatorily need a valid prototype in scope for
functions like printf to avoid undefined behaviour and
True.

that can be done through #include <stdio.h> only.

False. The requirement is for a valid prototype. stdio.h is arguably
the best place to get it but it can legally come from any place,
including code you type in.
But, the below code runs perfectly well without those
statment. Strange !!

What is strange is your conclusion that it ran perfectly well. Please
define perfectly well, or even regular well, WHEN THE BEHAVIOR IS
UNDEFINED. It would be nice if you could show us some reference for
what you want the term to mean..
int main(void)
{
int a = 1,b;
char t[10];
printf(a ?"one \n" : "zero \n") ;
scanf("%d",&b);
printf("b = %d \n",b);
strcpy(t,"Hello");
printf("%s \n",t);
return 0;
}

It works without the famous #include<stdio.h> .
Strange ? How is it possible ?

You have extremely bad luck and/or a poorly designed system. One of
the worst manifestations of undefined behavior is to do what the
programmer expected THIS TIME.
I use Visual C++ 2008 express edition for C compilation
and debugging.

Any ideas ?

Don't stick you fingers in any electric sockets.
 
C

CBFalconer

karthikbalaguru said:
I find that the below program works without the inclusion of the
stanard input/output library. I understand that we mandatorily
need a valid prototype in scope for functions like printf to
avoid undefined behaviour and that can be done through #include
<stdio.h> only. But, the below code runs perfectly well without
those statment. Strange !!

int main(void) {
int a = 1,b;
char t[10];
printf(a ?"one \n" : "zero \n") ;
scanf("%d",&b);
printf("b = %d \n",b);
strcpy(t,"Hello");
printf("%s \n",t);
return 0;
}

It works without the famous #include<stdio.h> .
Strange ? How is it possible ?

What's strange? You have undefined behaviour. That includes
apparently working.
 
R

Richard

Barry Schwarz said:
Does gcc support undefined behavior? Maybe you should ask in a gcc
group.

You don't use Gcc? I do. It does indeed support undefined behaviour.
 
R

Richard Tobin

Incorrect - it works without inclusion of the standard header. There's a
big difference. Most compilers automatically link to the standard
library (except for the parts declared in <math.h>), whether or not you
#include the relevant standard headers.
[/QUOTE]
Does gcc support that functionality ?

Yes, all unix C compilers do - if they didn't, it would break zillions
of Makefiles. Whether they require "-lm" to link the maths library
will probably depend just on whether there *is* a maths library; it
may just be included in the standard C library.

Make sure you've understood the difference between headers and
libraries, or you will face endless confusion.

-- Richard
 
R

Richard Tobin

It works without the famous #include<stdio.h> .
Strange ? How is it possible ?
[/QUOTE]
What's strange? You have undefined behaviour. That includes
apparently working.

It includes *actually* working.

Whether a missing declaration for printf() - assuming it gets past the
compiler - will break things depends on the system's function calling
conventions. If all functions are called in the same way (typically
by just pushing the values onto a stack), including variable-argument
ones, then there's nothing to go wrong. But you really don't want to
rely on this, and I recommend running your compiler with settings that
tell it to complain about all undeclared functions.

-- Richard
 
G

Guest

you really don't need to know the answer to this. In fact I'd say you
*should* not know this. If you do know it you should not rely on it.
For instance gcc is permitted to change it's behaviour in some future
release.
Be careful.  James is playing games with you over what is meant by "the
standard library".  He is jerking you around, pretending not to
understand what you mean by the term.

no he isn't, he is quite clearly distinguishing headers from libraries

To the original poster:

Did you read any of the responses you got before when you tried
to rely on undefined behaviour? Because if you don't read replies
there is little point in posting them!

For instance this is some of what I said before to you:
[<some X> doesn't have defined behaviour].

It exhibits "undefined behaviour"

Note well...
I was expecting undefined behaviour.

What do you think "undefined behaviour" *is*.
"When I ordered my car I didn't specify the colour.
They gave me a red one. Why didn't they give me
one with an Unspecified Colour?"
But, i got
an unexpected correct logical output in <some implementation>

how can you expect anything?

If The Standard leaves a behaviour undefined (or specifically
states that something results in undefined behaviour) then
The Implementor (the compiler writer) is permitted, by the standard,
to do anything he damn well pleases. Including the behaviour you
"expected" or didn't expect or... whatever.

I reiterate
***
If the behaviour is undefined then The Implementor (the compiler
writer)
is permitted, by the standard, to do anything he damn well pleases.
***
Any ideas ?


you have STILL not grokked UB in its fullness
 
R

Richard Bos

karthikbalaguru said:
I understand that we mandatorily need a valid prototype in scope for
functions like printf to avoid undefined behaviour and
that can be done through #include <stdio.h> only.
But, the below code runs perfectly well without those
statment. Strange !!

Did you get your "understanding" of undefined behaviour from jacob
navia, by any chance? You seem to suffer from the same delusion as he
does: that "not defined" _really_ means "defined to break". Well, guess
what: it doesn't.

Richard
 
R

Richard Tobin

Jack Klein said:
The fact that you keep asking questions like this, when you have BEEN
TOLD MANY TIMES that UNDEFINED BEHAVIOR does not PREVENT the program
from doing what you think is "works".

So either you have a VERY BAD MEMORY, or you are a TROLL.

Or perhaps he just wants to know why it works. The fact that the
standard allows it to work does not explain why it does.

-- Richard
 
C

CBFalconer

Richard said:
Or perhaps he just wants to know why it works. The fact that the
standard allows it to work does not explain why it does.

Then, at the very least, he should be asking on a newsgroup
dedicated to his opsys, compiler, library, and the appropriate
versions of such. Not here.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,995
Messages
2,570,230
Members
46,819
Latest member
masterdaster

Latest Threads

Top