473,385 Members | 1,351 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,385 software developers and data experts.

printf length modifier

Hello,

Does the following code invoke undefined behavior?

#include <stdio.h>
int main(void)
{
unsigned short int u = 42;
printf("%u\n", u);
return 0;
}

gcc doesn't seem to mind.
$ gcc -Wall -Wextra -std=c89 -pedantic zzz.c
$ ./a.out
42

Is it mandatory to add the 'h' length modifier in the format string?

unsigned short int u = 42;
printf("%hu\n", u);

Regards.
Apr 26 '07 #1
12 4409
Spoon wrote:
>
Does the following code invoke undefined behavior?

#include <stdio.h>
int main(void)
{
unsigned short int u = 42;
printf("%u\n", u);
return 0;
}
Yes.
>
gcc doesn't seem to mind.
$ gcc -Wall -Wextra -std=c89 -pedantic zzz.c
$ ./a.out
42

Is it mandatory to add the 'h' length modifier in the format string?
Yes. Add the -O (capital letter) option to the gcc run.

--
<http://www.cs.auckland.ac.nz/~pgut001/pubs/vista_cost.txt>
<http://www.securityfocus.com/columnists/423>
<http://www.aaxnet.com/editor/edit043.html>
cbfalconer at maineline.net
--
Posted via a free Usenet account from http://www.teranews.com

Apr 26 '07 #2
CBFalconer wrote:
Spoon wrote:
>Does the following code invoke undefined behavior?

#include <stdio.h>
int main(void)
{
unsigned short int u = 42;
printf("%u\n", u);
return 0;
}

Yes.
>gcc doesn't seem to mind.
$ gcc -Wall -Wextra -std=c89 -pedantic zzz.c
$ ./a.out
42

Is it mandatory to add the 'h' length modifier in the format string?

Yes. Add the -O (capital letter) option to the gcc run.
$ gcc -O -Wall -Wextra -std=c89 -pedantic zzz.c
$ ./a.out
42

$ gcc -O3 -Wall -Wextra -std=c89 -pedantic zzz.c
$ ./a.out
42

:-)

Aren't short int parameters "widened" to int in variadic function calls?

Regards.
Apr 26 '07 #3
Spoon wrote, On 26/04/07 10:33:
Hello,

Does the following code invoke undefined behavior?

#include <stdio.h>
int main(void)
{
unsigned short int u = 42;
printf("%u\n", u);
return 0;
}
<snip>
Is it mandatory to add the 'h' length modifier in the format string?

unsigned short int u = 42;
printf("%hu\n", u);
unsigned short is likely to be promoted to int rather than signed int,
so using %u is lying. Anyway, why would you want to use a possibly
incorrect format specifier when you know the definitely correct one?
--
Flash Gordon
Apr 26 '07 #4
Spoon wrote, On 26/04/07 12:20:
CBFalconer wrote:
>Spoon wrote:
>>Does the following code invoke undefined behavior?

#include <stdio.h>
int main(void)
{
unsigned short int u = 42;
printf("%u\n", u);
return 0;
}

Yes.
<snip>
>>Is it mandatory to add the 'h' length modifier in the format string?

Yes. Add the -O (capital letter) option to the gcc run.
<snip>
Aren't short int parameters "widened" to int in variadic function calls?
You are using unsigned short, which could be widened to int (most
probable) or unsigned int, and using the format specifier for an
unsigned int. int and unsigned int are NOT the same thing.

There is also the big question of why you do not want to use what you
know is definitely the correct format specifier.
--
Flash Gordon
Apr 26 '07 #5
Flash Gordon wrote:
Spoon wrote, On 26/04/07 12:20:
>CBFalconer wrote:
>>Spoon wrote:
Does the following code invoke undefined behavior?

#include <stdio.h>
int main(void)
{
unsigned short int u = 42;
printf("%u\n", u);
return 0;
}

Yes.

<snip>
>>>Is it mandatory to add the 'h' length modifier in the format string?

Yes. Add the -O (capital letter) option to the gcc run.

<snip>
>Aren't short int parameters "widened" to int in variadic function calls?

You are using unsigned short, which could be widened to int (most
probable) or unsigned int, and using the format specifier for an
unsigned int. int and unsigned int are NOT the same thing.
(Hair-splitting ahead) AFAIU, for the value 42, int and unsigned int are
equivalent because both conversions are well-defined.
There is also the big question of why you do not want to use what you
know is definitely the correct format specifier.
u is, in fact, an uint16_t and I don't know for sure that u is an
unsigned short int. It might be an unsigned int.

Regards.
Apr 26 '07 #6
Spoon wrote, On 26/04/07 14:31:
Flash Gordon wrote:
>Spoon wrote, On 26/04/07 12:20:
>>CBFalconer wrote:
Spoon wrote:
Does the following code invoke undefined behavior?
>
#include <stdio.h>
int main(void)
{
unsigned short int u = 42;
printf("%u\n", u);
return 0;
}

Yes.

<snip>
>>>>Is it mandatory to add the 'h' length modifier in the format string?

Yes. Add the -O (capital letter) option to the gcc run.

<snip>
>>Aren't short int parameters "widened" to int in variadic function calls?

You are using unsigned short, which could be widened to int (most
probable) or unsigned int, and using the format specifier for an
unsigned int. int and unsigned int are NOT the same thing.

(Hair-splitting ahead) AFAIU, for the value 42, int and unsigned int are
equivalent because both conversions are well-defined.
True, but it is reasonable to assume that in the real code other values
will be used. It is not unreasonable to expect that some of those values
will be too large to fit in a signed short, or why bother with the extra
typing?
>There is also the big question of why you do not want to use what you
know is definitely the correct format specifier.

u is, in fact, an uint16_t and I don't know for sure that u is an
unsigned short int. It might be an unsigned int.
If this is C99 code then I believe there is a macro provided in C99 to
solve this problem. Otherwise, cast the value to a known type for printing.
printf("%u\n", (unsigned int)u);
Or, alternatively, as you know that any value that will fit in an
unsigned 16 bit integer will fit in an unsigned short (which may be more
than 16 bits, but not less), cast to unsigned short and use the h modifier.
--
Flash Gordon
Apr 26 '07 #7
Spoon wrote:
Flash Gordon wrote:
Spoon wrote, On 26/04/07 12:20:
CBFalconer wrote:
Spoon wrote:
Does the following code invoke undefined behavior?

#include <stdio.h>
int main(void)
{
unsigned short int u = 42;
printf("%u\n", u);
return 0;
}

Yes.
<snip>
>>Is it mandatory to add the 'h' length modifier in the format string?

Yes. Add the -O (capital letter) option to the gcc run.
<snip>
Aren't short int parameters "widened" to int in variadic function calls?
You are using unsigned short, which could be widened to int (most
probable) or unsigned int, and using the format specifier for an
unsigned int. int and unsigned int are NOT the same thing.

(Hair-splitting ahead) AFAIU, for the value 42, int and unsigned int are
equivalent because both conversions are well-defined.
Huh? I really don't understand what you're trying to say here. Could
you please explain?
There is also the big question of why you do not want to use what you
know is definitely the correct format specifier.

u is, in fact, an uint16_t and I don't know for sure that u is an
unsigned short int. It might be an unsigned int.
The format specifier for uint16_t is PRIu16.

#include <stdio.h>
#include <inttypes.h>

#ifndef UINT16_MAX
#error uint16_t not supported
#endif

int main(void)
{
uint16_t u = 42;
printf("%" PRIu16 "\n", u);
return 0;
}

Apr 26 '07 #8
Harald van Dijk wrote, On 26/04/07 18:51:
Spoon wrote:
<snip>
>(Hair-splitting ahead) AFAIU, for the value 42, int and unsigned int are
equivalent because both conversions are well-defined.

Huh? I really don't understand what you're trying to say here. Could
you please explain?
The standard guarantees that the representation of all positive values
of int is the same as the representation of those values in an unsigned
int. At least, I assume that is what Spoon meant, although if so it
could be phrased better.
--
Flash Gordon
Apr 26 '07 #9
Flash Gordon wrote:
Harald van Dijk wrote, On 26/04/07 18:51:
Spoon wrote:

<snip>
(Hair-splitting ahead) AFAIU, for the value 42, int and unsigned int are
equivalent because both conversions are well-defined.
Huh? I really don't understand what you're trying to say here. Could
you please explain?

The standard guarantees that the representation of all positive values
of int is the same as the representation of those values in an unsigned
int. At least, I assume that is what Spoon meant, although if so it
could be phrased better.
Thanks for the explanation. I don't think there's any prohibition
against an implementation passing the object type along with the
value, and bombing out if the passed type does not exactly match the
expected type for printf(), but only bombing out if the passed type
does not loosely match the expected type for va_arg(). Aside from an
extremely strict debugging implementation though, I can't imagine why
anyone would want to do that.

Apr 26 '07 #10
Spoon <de*****@localhost.comwrites:
Flash Gordon wrote:
>Spoon wrote, On 26/04/07 12:20:
>>CBFalconer wrote:
Spoon wrote:
Does the following code invoke undefined behavior?
>
#include <stdio.h>
int main(void)
{
unsigned short int u = 42;
printf("%u\n", u);
return 0;
}

Yes.
<snip>
>>>>Is it mandatory to add the 'h' length modifier in the format string?

Yes. Add the -O (capital letter) option to the gcc run.
<snip>
>>Aren't short int parameters "widened" to int in variadic function calls?
You are using unsigned short, which could be widened to int (most
probable) or unsigned int, and using the format specifier for an
unsigned int. int and unsigned int are NOT the same thing.

(Hair-splitting ahead) AFAIU, for the value 42, int and unsigned int
are equivalent because both conversions are well-defined.
Conversion has nothing to do with it. Conversion between int and
double is well-defined, but passing a double argument for a "%d"
format invokes undefined behavior. No conversion, other than argument
promotions, occurs for variadic arguments.

It's true that the value 42 is guaranteed to have the same
*representation* in types int and unsigned int. Specifically, C99
6.2.5p9 says:

The range of nonnegative values of a signed integer type is a
subrange of the corresponding unsigned integer type, and the
representation of the same value in each type is the same.

with a footnote:

The same representation and alignment requirements are meant to
imply interchangeability as arguments to functions, return values
from functions, and members of unions.

So you can look carefully through the standard for proof that the code
will work properly whether the argument is promoted to int or to
unsigned int (note that this depends on a footnote, which is
nonnormative). Note that you'll also need to depend on the
implementer getting this right. It's also likely that the argument
will be promoted to int on all the platforms you use, so you'll never
have a chance to test the case where it's promoted to unsigned int,
just in case you missed something.

Or you can write simpler code that doesn't depend on a potentially
shaky line of reasoning.
>There is also the big question of why you do not want to use what
you know is definitely the correct format specifier.

u is, in fact, an uint16_t and I don't know for sure that u is an
unsigned short int. It might be an unsigned int.
So convert it to unsigned int and use "%u".

Incidentally, there's another subtle issue here. The standard's
description of printf() describes the required formats for various
types. It's almost certainly safe to assume that printf() uses the
same mechanisms as a user-written variadic function, so you can safely
assume that argument promotion occurs as you would expect. But the
standard doesn't *quite* come out and say so. (There was a lengthy
discussion of this in comp.std.c a while ago.) I don't think it's
anything to worry about, but it's enough to make me more cautious with
format strings than I absolutely need to be.

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <* <http://users.sdsc.edu/~kst>
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
Apr 26 '07 #11
On 26 Apr 2007 13:29:45 -0700, Harald van D?k <tr*****@gmail.com>
wrote in comp.lang.c:
Flash Gordon wrote:
Harald van D?k wrote, On 26/04/07 18:51:
Spoon wrote:
<snip>
>(Hair-splitting ahead) AFAIU, for the value 42, int and unsigned int are
>equivalent because both conversions are well-defined.
>
Huh? I really don't understand what you're trying to say here. Could
you please explain?
The standard guarantees that the representation of all positive values
of int is the same as the representation of those values in an unsigned
int. At least, I assume that is what Spoon meant, although if so it
could be phrased better.

Thanks for the explanation. I don't think there's any prohibition
against an implementation passing the object type along with the
value, and bombing out if the passed type does not exactly match the
expected type for printf(), but only bombing out if the passed type
does not loosely match the expected type for va_arg(). Aside from an
extremely strict debugging implementation though, I can't imagine why
anyone would want to do that.
Actually there is such a prohibition, 6.5.2.2 p6. It applies to both
functions without prototypes and to the variable arguments of variadic
functions:

<begin>
If the expression that denotes the called function has a type that
does not include a prototype, the integer promotions are performed on
each argument, and arguments that have type float are promoted to
double. These are called the default argument promotions. If the
number of arguments does not equal the number of parameters, the
behavior is undefined. If the function is defined with a type that
includes a prototype, and either the prototype ends with an ellipsis
(, ...) or the types of the arguments after promotion are not
compatible with the types of the parameters, the behavior is
undefined. If the function is defined with a type that does not
include a prototype, and the types of the arguments after promotion
are not compatible with those of the parameters after promotion, the
behavior is undefined, except for the following cases:

— one promoted type is a signed integer type, the other promoted type
is the corresponding unsigned integer type, and the value is
representable in both types;

— both types are pointers to qualified or unqualified versions of a
character type or void.
<end>

So it makes no difference if the unsigned short is promoted to signed
or unsigned int, the actual int object has exactly the same bit
representation and is passed the same way.

--
Jack Klein
Home: http://JK-Technology.Com
FAQs for
comp.lang.c http://c-faq.com/
comp.lang.c++ http://www.parashift.com/c++-faq-lite/
alt.comp.lang.learn.c-c++
http://www.club.cc.cmu.edu/~ajo/docs/FAQ-acllc.html
Apr 27 '07 #12
Jack Klein wrote:
On 26 Apr 2007 13:29:45 -0700, Harald van D?k <tr*****@gmail.com>
wrote in comp.lang.c:
Flash Gordon wrote:
Harald van D?k wrote, On 26/04/07 18:51:
Spoon wrote:
>
<snip>
>
(Hair-splitting ahead) AFAIU, for the value 42, int and unsigned int are
equivalent because both conversions are well-defined.

Huh? I really don't understand what you're trying to say here. Could
you please explain?
>
The standard guarantees that the representation of all positive values
of int is the same as the representation of those values in an unsigned
int. At least, I assume that is what Spoon meant, although if so it
could be phrased better.
Thanks for the explanation. I don't think there's any prohibition
against an implementation passing the object type along with the
value, and bombing out if the passed type does not exactly match the
expected type for printf(), but only bombing out if the passed type
does not loosely match the expected type for va_arg(). Aside from an
extremely strict debugging implementation though, I can't imagine why
anyone would want to do that.

Actually there is such a prohibition, 6.5.2.2 p6.
6.5.2.2p6 describes function calls where the function declaration
lacks a prototype. Any definition of printf must include a prototype.
6.5.2.2p7 describes function calls where the function declaration
includes a prototype, and contains no exception similar to what you
quoted.

Apr 27 '07 #13

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

7
by: sunfiresg | last post by:
During an interview, I am asked to answer a question: Printf is a major formatted output function provided by the standard C library. Printf accepts a formatting string followed by a various...
9
by: Arthur J. O'Dwyer | last post by:
I have a situation where I want to use one of two different format strings in a 'printf' call, depending on a flag set by the user. One of the calls uses a field width modifier, and the other one...
4
by: Gaijinco | last post by:
I read somewhere that printf and scanf had "advanced features" and they point to: scanf("%",line); // line is a string as an example, where scanf() acts like gets() I try to look of more of...
5
by: dank | last post by:
http://msdn2.microsoft.com/en-us/library/tcxf1dw6.aspx describes the integer format modifiers accepted by Microsoft's printf. ...
6
by: ray.webster | last post by:
Should the following work *if* I have a c99 compiler please? #include <stdio.h> int main(void) { size_t t = 42; # if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
4
by: chandanlinster | last post by:
hello everybody, as i was going through the "printf" man page, i came across this statement. printf("%*d", width, num); what does "*" mean?
34
by: Old Wolf | last post by:
Is there any possible situation for printf where %hd causes a different result to %d, and the corresponding argument was of type 'short int' ?
28
by: laikon | last post by:
Hello, everyone: this is about overflow in C and C++. int c = 400; printf("%c", c); it print ? on screen, and ascii of '?' is 63. but
43
by: Jrdman | last post by:
someone has an idea on how the printf function is programmed ?
1
by: CloudSolutions | last post by:
Introduction: For many beginners and individual users, requiring a credit card and email registration may pose a barrier when starting to use cloud servers. However, some cloud server providers now...
0
by: Faith0G | last post by:
I am starting a new it consulting business and it's been a while since I setup a new website. Is wordpress still the best web based software for hosting a 5 page website? The webpages will be...
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 3 Apr 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome former...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: aa123db | last post by:
Variable and constants Use var or let for variables and const fror constants. Var foo ='bar'; Let foo ='bar';const baz ='bar'; Functions function $name$ ($parameters$) { } ...
0
by: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.