Why do i get runtime error ?

  • Thread starter karthikbalaguru
  • Start date
K

karthikbalaguru

Hi,

Is it not possible to use %f and print #define's ?

#define MAX_VAL 100
int main(void)
{
printf("%f", MAX_VAL);
return 0;
}

I get runtime error for the above code .
Any specific reason ?

Thx in advans,
Karthik Balaguru
 
A

Antoninus Twink

Is it not possible to use %f and print #define's ?

Yes, as long as what you #define is a double.
#define MAX_VAL 100
int main(void)
{
printf("%f", MAX_VAL);
return 0;
}

I get runtime error for the above code .

That's surprising - it's more likely that you'd get garbage.

You tell printf() that you'll provide it with one argument after the
format string, of type double. But you actually give it an argument of
type int. Typically, an int will be 4 bytes wide, whereas a double is 8
bytes wide. So printf() tries to read memory (quite likely a register,
in fact) that isn't yours to read, and probably isn't initialized.

Even if you have a system where int and double are the same size, if you
try to interpret the bits making up 100 as an int as a double then you
almost certainly won't get 100.0 back.

Try

#define MAX_VAL 100.

instead, or change the printf() format specifier to %d.
 
K

karthikbalaguru

I guess you forgot to mention that you have

#include <stdio.h>

here, didn't you?

Yes said:
Yes, it's because you're not honest with printf(). You tell it
via '%f' that it can expect a double value but what you give it
insteadis an integer. Now printf() tries to interpret the
data it receives as a double but the data may simply be nor
a valid double and that may result in a runtime error.

But, shouldn't it give a garbage value rather than runtime error ?

Thx in advans,
Karthik Balaguru
 
B

Bart

Hi,

Is it not possible to use %f and print #define's ?

#define MAX_VAL 100
int main(void)
{
     printf("%f", MAX_VAL);
     return 0;

}

I get runtime error for the above code .
Any specific reason ?

The error has been explained but this can easily be picked up by your
compiler. Adjust the warning levels for it.
 
K

Keith Thompson

Bart said:
The error has been explained but this can easily be picked up by your
compiler. Adjust the warning levels for it.

That depends on the compiler. gcc, for example, can diagnose
mismatches between a printf format string and arguments (if the format
is given as a string literal), but I don't know whether other
compilers can do so.

The bottom line is that it's entirely up to you, the programmer, to
make sure that your format string is correct for the argument types
you're feeding it. Some compilers might be able to help you diagnose
the problem, but you can't count on it. The only reliable solution is
to get it right in the first place.
 
M

Martin Ambuhl

karthikbalaguru said:
Is it not possible to use %f and print #define's ?

Of course it is.
#define MAX_VAL 100
int main(void)
{
printf("%f", MAX_VAL);
return 0;
}
I get runtime error for the above code .
Any specific reason ?


The result of replacing MAX_VAL with its definition is
printf("%f", 100);

You have not provided any indication that you have included <stdio.h>.
printf() is variadic, and so provides in its prototype (in <stdio.h>) no
type information beyond the first argument. Even if you did not need a
prototype for the variadic function, a function without one has no type
information about any of its arguments. You must, from C99 on, include
at least a declaration of a function providing the return type before
using it. For example
int crap(); /* minimum declaration */
Before C99 this was not needed for functions with a fixed number of
arguments, since a function without declaration was assumed to return
int. The days of implicit int are gone. But this minimum declaration
provides no information about its arguments. For that you need a
prototype. If you call a function with arguments of the wrong type and a
prototype is not present, the error cannot be diagnosed by the compiler
and the likely result is a runtime error. A function with a variable
number of arguments (a variadic function) still provides no information
for the variable part of the argument list (the "..." part). Any
expression that appears as an argument in a function call that is not
governed by a prototype or that appears as an argument in the "..." part
of a prototype is converted according to the usual unary conversions
(except a float is always promoted to a double).

But 100 is an integral value, and the usual rules for integral arguments
in absence of a prototype apply. Look up "usual function argument
conversions" in your C textbook. So you are attempting to interpret an
int using a specifer for a double ("%f"). You can fix this in several ways.
1) change the define so MAX_VAL is a floating-point value:
#define MAX_VAL 100. /* notice the '.' */
2) use the correct specifier for an int:
printf("%d", MAX_VAL);
3) make the second argument to printf match the specifier:
printf("%f", (double) MAX_VAL);
 
K

karthikbalaguru

I guess you forgot to mention that you have

#include <stdio.h>

here, didn't you?


Yes, it's because you're not honest with printf(). You tell it
via '%f' that it can expect a double value but what you give it
 insteadis an integer. Now printf() tries to interpret the
data it receives as a double but the data may simply be nor
a valid double and that may result in a runtime error.

Thinking over this, i got a strange query.
But, Why doesn't handle these execptions and convey something like
' %d should be used '
or
'#define's need %d while passed to printf'
etc...

Any ideas ? Anyone working on such kind of improvements ?

Thx in advans,
Karthik Balaguru
 
J

Jens Thoms Toerring

Thinking over this, i got a strange query.
But, Why doesn't handle these execptions and convey something like
' %d should be used '
or
'#define's need %d while passed to printf'
etc...

Actually, some compilers warn you for e.g.

prinf( "%f", 100 );

if you raise the warning level high enough. E.g. gcc, when started
with '-W', tells you about that line

warning: format '%f' expects type 'double', but argument 2 has type 'int'

But it can only do that if it gets a format string that is known
at compile time. On the other hand, there are situations where
format strings are only assembled at run time and then the com-
piler can't do anything about it. To catch also those cases
checks to be done at run time would have to be inserted before
each call of printf() (and similar functions). I guess there's
nothing in the C standard that would forbid this but, probably
since it might incur a rather high overhead, I haven't seen it
done (which doesn't mean it doesn't exist!). Traditionally, in
C very few run time checks are done automatically since all of
them tend to reduce execution speed, so the programmer has to
be on the look-out to avoid this and other errors.

Regards, Jens
 
B

Bruce Cook

Jens said:
Actually, some compilers warn you for e.g.

prinf( "%f", 100 );

if you raise the warning level high enough. E.g. gcc, when started
with '-W', tells you about that line

warning: format '%f' expects type 'double', but argument 2 has type 'int'

But it can only do that if it gets a format string that is known
at compile time. On the other hand, there are situations where
format strings are only assembled at run time and then the com-
piler can't do anything about it. To catch also those cases
checks to be done at run time would have to be inserted before
each call of printf() (and similar functions). I guess there's
nothing in the C standard that would forbid this but, probably
since it might incur a rather high overhead, I haven't seen it
done (which doesn't mean it doesn't exist!). Traditionally, in
C very few run time checks are done automatically since all of
them tend to reduce execution speed, so the programmer has to
be on the look-out to avoid this and other errors.

One of the base philosophys behind the compiler it that it will just build
code that does the job, you the programmer are responsible for , for
example, making sure you have the correct arguments. For the most part
there is no runtime checking such as other languages do (bounds etc).

What's actually happening with that printf(), is that you are simply calling
a library function with a set of arguments. The first argument of printf()
is a string pointer that the function uses to control the formatting of it's
output, specifying string literals, and the format/data type of the
remaining arguments.

printf() is not special, although a compiler could be educated to know about
printf() and friends and do some additional checking. In other languages
I/O operations are handled by language constructs, so therefore compile and
run time checking can be applied. in C, it's just another library function.

As Jens points out, parameters may be passed to printf() in a variety of way
that would make their data type obvious at runtime. This would mean a great
deal of overhead doing runtime checking. C as a language generally doesn't
hold your hand, it lets you make the most egregious mistakes and happily
assumes that you know what you're doing. While later compilers will warn
you about a raft of common mistakes, some things like the content of strings
C is really not interested in.

Bruce
 
K

karthikbalaguru

Actually, some compilers warn you for e.g.

prinf( "%f", 100 );

if you raise the warning level high enough. E.g. gcc, when started
with '-W', tells you about that line

warning: format '%f' expects type 'double', but argument 2 has type 'int'

Interesting !! I will raise the warning level .
But it can only do that if it gets a format string that is known
at compile time. On the other hand, there are situations where
format strings are only assembled at run time and then the com-
piler can't do anything about it.
To catch also those cases
checks to be done at run time would have to be inserted before
each call of printf() (and similar functions).


hmm. But, what are the scenarios in which format strings for
printf are only assembled at run time ?

Thx in advans,
Karthik Balaguru
 
B

Ben Bacarisse

Golden California Girls said:
That might be where the user can tell your program how many digits
wide it wants a column of output.

You might see such code, but for that specific usage there is a better
option: the * field width:

int how_wide;
/* code that set how wide via some magic */
printf("%*d", how_wide, x);
 
C

CBFalconer

karthikbalaguru said:
(e-mail address removed) (Jens Thoms Toerring) wrote:
.... snip ...


hmm. But, what are the scenarios in which format strings for
printf are only assembled at run time ?

For example, when a format string is formed and passed to printf at
run time.

...
printf(s, /* args */);

where s is a char* formed elsewhere.

7.19.6.3 The printf function

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

Description

[#2] The printf function is equivalent to fprintf with the
argument stdout interposed before the arguments to printf.

Returns

[#3] The printf function returns the number of characters
transmitted, or a negative value if an output or encoding
error occurred.
 
J

James Kuyper

karthikbalaguru said:
Thinking over this, i got a strange query.
But, Why doesn't handle these execptions and convey something like
' %d should be used '

Because the compiler can't be sure whether its the format string or the
argument that is incorrect. It can only be sure that there's a
mis-match. In my experience, most such type mismatches are a side-effect
of a mismatch between the number of specifiers and the number of
arguments, rather than to use of the wrong format specifier - but YYMV.
or
'#define's need %d while passed to printf'

Well, it didn't say that, because that's false. Consider the following:

#define STRING "Hello, world!"
#define FLOAT 5.7
#defind POINTER &object

I would not recommend using %d with any of those macros. The fact that
they are macros is irrelevant. You get exactly the same problem with
printf("%f", 100) as with printf("%f", MAX_VAL).
 
A

Andrew Smallshaw

Eric Sosman said:
The only thing you know about undefined behavior is that you
can know nothing about it; [...]

True in C terms, and thus correct for comp.lang.c. Nevertheless, in
platform-specific terms, UB can be very predictable and immensely
valuable. Consider, for example, memory-mapped I/O - reading
directly from, or writing directly to, I/O memory is a very
powerful technique on platforms where it works.

But on those platforms such behaviour is implementation-defined
rather than undefined. I have come across cases where really
'undefined' behaviour changed from one edition of the compiler to
the next. Someone had tested what the compiler did in a particular
case and assumed that the behaviour in that instance was somehow
set in stone. It took a lot of effort to sort that mess out.
 
K

Kaz Kylheku

just not by the rules of C, that's all. There are other universes
of discourse other than C. Off-topic here they may be, but that
doesn't mean they don't exist.

.... nor that they don't exist /here/, nor that any of us have
stayed out of them!
Sure. Once you leave the guarantees of C behind, you are at the
mercy of other forces.

C has guarantees now? Just money back, or are some damages covered?
 
K

Kaz Kylheku

Kaz Kylheku said:


It depends who you listen to.

"However, the C standard does guarantee the collating sequence for
the character literals '0' through '9'." - Kaz Kylheku, 27
September 1996

Ah, 1996. That was still in pedantic bootcamp.

Clearly wrong.
"Languages that, unlike C, do not guarantee any particular order of
storage of members of structures, permit compilers to generate an
optimal, or nearly so, packing for a given type." - Kaz Kylheku, 31
May 2000

Blatantly wrong. Should be ``do not require''.
"What is guaranteed is that, since stdout is line buffered by
default, the contents of the output buffer will be flushed to the
environment each time a newline character is printed." - Kaz
Kylheku, 24 July 2000

Should be ``What is required''.

Who wrote this crap? Must have been that Kaz that Chucky remembers
``so fondly''.
"It's stated in the standard, so a conforming C implementation must
ensure that '0' through '9' are consecutive positive integers. But
that doesn't amount to a guarantee.
A guarantee would have to be
some kind of binding document from a compiler vendor promising that
it is true, and stipulating some kind of remedy if it is found to
be false, like your money back or whatever." - Kaz Kylheku, 10 June
2001

That's interesting, isn't it! It's exactly the same subject matter in 1996, the
question of the characters '0' through '9', but a completely different
presentation.

You see, maybe we had a pedantic, but convincing little discussion about the
use of ``guarantee'' in the intervening time.

Today it is 2009, so we can't slip back to the mistakes from before 2001.

Can you catch me after 2001 in c.l.c?

Ah there is one case in 2002 where I wrote about something not being
guaranteed; it's true of course, so you cannot say that I am wrong, but it
didn't occur to me that it's /vacuously/ true and thus a useless non-fact. I.e.
it fails to be the pertinent statement that I should have made, namely that
that the behavior is not /required/. Well, vacuously right is not wrong.
I will take whatever ``not wrong'' I can get. :)

How about other newsgroups? One more minor slipup in comp.lang.lisp in 2002,
when discussing an interface contract between some module that provides macros,
and code that uses it, and the possibility of some guarantees related to
referential hygiene. (I could make some backpedaling arguments here about how
this is not about a standard document, but implementations of code, but I
won't).

In 2008 I used "guarantee" in that newsgroup, but in strictly mathematical
sense; i.e. related to a pure mathematical guarantee. If you walk around a
congruence based on a prime modulus in some fixed increments, you are
guaranteed (mathematically) to cover all elements of that congruence.
Based on this (admittedly small) sample, three out of four Kazes
think that C provides guarantees.

If we grant that my misuse can excuse yours at all, my /historic/ misuse
certainly cannot excuse your /current/ misuse, only your own /historic/ misuse.

``I owned slaves? Well, so did you.'' -- valid

``I own slaves? Well, so did you.'' -- invalid

Otherwise you could use this argument schema to excuse yourself for being wrong
about /anything whatsoever/ that anyone else in the debate could be shown not
to have known once upon a time. And once upon a time, we all knew nothing.

How about no excuses? I was pitifully wrong about some things that I'm not
wrong out anymore, but I'm horribly wrong about some other things (that others
are not wrong about), etc.

Once upon a time people could come to this newsgroup for a friendly exchange of
calling each other's nonsense. One lurked in the shadows, one hand on the
handle of his katana, waiting to leap out and strike down Dan Pop or Lawrence
Kirby upon the slightest sign (or should we say odor) of bullschildt.
It was just a sport.
 
C

CBFalconer

Richard said:
Kaz Kylheku said:

It depends who you listen to.

"However, the C standard does guarantee the collating sequence for
the character literals '0' through '9'." - Kaz Kylheku, 27
September 1996

"Languages that, unlike C, do not guarantee any particular order of
storage of members of structures, permit compilers to generate an
optimal, or nearly so, packing for a given type." - Kaz Kylheku, 31
May 2000

"What is guaranteed is that, since stdout is line buffered by
default, the contents of the output buffer will be flushed to the
environment each time a newline character is printed." - Kaz
Kylheku, 24 July 2000

"It's stated in the standard, so a conforming C implementation must
ensure that '0' through '9' are consecutive positive integers. But
that doesn't amount to a guarantee. A guarantee would have to be
some kind of binding document from a compiler vendor promising that
it is true, and stipulating some kind of remedy if it is found to
be false, like your money back or whatever." - Kaz Kylheku, 10 June
2001

Based on this (admittedly small) sample, three out of four Kazes
think that C provides guarantees.

Kaz2 recently posted that he had last been active in 1995. Even
allowing for bit dropping in his memory, that and your dates above
tend to disprove his identity with Kaz1. I suspect he has been on
a Google search.

I also seem to vaguely recall that Kaz1 was a student in Helsinki.
 
K

Kaz Kylheku

Kaz2 recently posted that he had last been active in 1995. Even

Only as far as ``first'' and ``last'' can be regarded as interchangeable.
I also seem to vaguely recall that Kaz1 was a student in Helsinki.

I assure everyone no version of Kaz has ever set foot in Scandinavia,
though by all accounts it's a nice part of the world.

All versions of Kaz are a software developer in Vancouver, Canada.
 
A

Antoninus Twink

I recall drawing blood not only from both of the above, but also from
Steve Summit and, best of all, Chris Torek

Heathfield, your arrogance is truly breathtaking.

You think you've filled Chris Torek's boots, but in fact you're not fit
to lace them.
 
R

Richard Bos

CBFalconer said:
Kaz2 recently posted that he had last been active in 1995. Even
allowing for bit dropping in his memory, that and your dates above
tend to disprove his identity with Kaz1. I suspect he has been on
a Google search.

I also seem to vaguely recall that Kaz1 was a student in Helsinki.

Your memory is pitiful, in both cases. Old age will do that to you, but
that's no excuse not to check.

FYI, the Fin was Joona Palaste, who was more civilised that anyone
currently posting to this group. I miss _his_ contributions more than
almost any other ex-regular, but I suspect he doesn't miss this cesspit
at all.

Richard
 

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,982
Messages
2,570,190
Members
46,736
Latest member
zacharyharris

Latest Threads

Top