views:

409

answers:

6

hello all

I stumbled across something "interesting" and I cant put my finger why the behaviour isn't coherent.

Check this code.

char buf[100];
sprint(buf,"%s",bla);

Simple, right. It's easy to understand what is going on when bla is a NULL pointer.

This should always segfault right!?

In one machine the executable segfaults, on another (my development machine), it's just business as usual.

My devel PC is running Windows7 and I'm compiling with gcc/MingW. The computer where this is crashing is XP and it does have Visual studio 6 installed.

Why on earth doesn't this crash on my PC!?

Cheers

+3  A: 

Because printing a null reference as a string is (as far as I know, haven't verified with standards) undefined. Many systems will just output (null) in the result.

It's the same with the other printf functions:

printf ("%s", NULL); // Outputs (null) to the console on some systems but can crash others
Isak Savo
+1  A: 

Apart from that, a segfault is never guaranteed. If it occurs, there is an error somewhere; but having an error somewhere doesn't imply a segfault.

Frederik Slijkerman
+1  A: 

This should always segfault right!?

No. It depends on the implementation of the sprintf function that came with the standard library of the compiler.

As far as I know sprintf specification doesn't say you should provide a non-null address.

utnapistim
+11  A: 

This should always segfault right!?

No. This invokes undefined behavior. A segmentation fault is but one of many possible results of invoking UB.

sbi
+1: But this raises the following question: is there a way to ensure that something will cause a `SEGFAULT` ? (`kill my_program SEGFAULT` is not an answer)
ereOn
`raise(SIGSEGV);` Or, while there's no standard that says this must work, *(char *)0=0; is also pretty reliable.
R..
+1 Undefined behavior is called 'undefined' for a reason.
Matthieu M.
+27  A: 

ISO C99: 7.19.6.3 The printf function

Synopsis

 #include <stdio.h>
 int printf(const char * restrict format, ...);

The printf function is equivalent to fprintf with the argument stdout interposed before the arguments to printf.

7.19.6.1 The fprintf function

7.19.6.1.9

If a conversion specification is invalid, the behavior is **undefined**. If any argument is not the correct type for the corresponding conversion specification, the behavior is **undefined**.

So your code invokes Undefined Behavior [(ISO C99 3.4.3) behavior, upon use of a nonportable or erroneous program construct or of erroneous data, for which this International Standard imposes **no requirements**]

This should always segfault right!?

Not necessarily, Undefined Behavior means anything can happen.

Prasoon Saurav
Nicely researched, Prasoon, `+1` from me!
sbi
Thanks @sbi :)....
Prasoon Saurav
One day, I'm going to make a compiler that starts playing *Flight of the Valkyrie* every time undefined behavior is invoked.
rlbond
A: 

It all depends on what bla is pointing to at the time. What sprintf() will do is copy all of the characters pointed to by bla until it encounters a zero (0x00) character.

If it encounters a zero character before it reaches the limit of buf[100], then, there's no segfault because we are not writing beyond the buf limit.

Also, in some systems, if bla points to a read-access protected memory region, it may also cause a segfault as soon as the data is read.

hopia