By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
446,194 Members | 888 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 446,194 IT Pros & Developers. It's quick & easy.

strange warning

P: n/a
I got a warning from the following statement:

fprintf(point_file, "CONTOUR\nCLOSE\n%d\n", curve.size());

warning: format '%d' expects type 'int', but argument 3 has type
'size_t'

should I change the coding to

fprintf(point_file, "CONTOUR\nCLOSE\n%u\n", curve.size());

?

Thanks all.

Jul 10 '06 #1
Share this Question
Share on Google+
24 Replies


P: n/a
asdf wrote:
I got a warning from the following statement:

fprintf(point_file, "CONTOUR\nCLOSE\n%d\n", curve.size());

warning: format '%d' expects type 'int', but argument 3 has type
'size_t'

should I change the coding to

fprintf(point_file, "CONTOUR\nCLOSE\n%u\n", curve.size());

?
It could be that you need %Lu if sizeof(size_t) sizeof(int) on
your system. Also, see the documentation for your compiler about
what format string to use to print out 'size_t'.

V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask
Jul 10 '06 #2

P: n/a
asdf wrote:
I got a warning from the following statement:

fprintf(point_file, "CONTOUR\nCLOSE\n%d\n", curve.size());

warning: format '%d' expects type 'int', but argument 3 has type
'size_t'

should I change the coding to

fprintf(point_file, "CONTOUR\nCLOSE\n%u\n", curve.size());

?
...
You should explicitly cast the return value of 'curve.size()' to some built-in
integral type that is sufficiently large to hold the value, and then use the
format specifier for that type. For example

fprintf(point_file, "CONTOUR\nCLOSE\n%lu\n", (unsigned long) curve.size());

Your platform might also provide an implementation-specific format specifier for
printing 'size_t'. So you might decide to use that instead (assuming that return
type of 'size_t' is a part of the interface specification of that 'size()' method).

--
Best regards,
Andrey Tarasevich
Jul 11 '06 #3

P: n/a
Andrey Tarasevich wrote:
asdf wrote:
>>I got a warning from the following statement:

fprintf(point_file, "CONTOUR\nCLOSE\n%d\n", curve.size());

warning: format '%d' expects type 'int', but argument 3 has type
'size_t'

should I change the coding to

fprintf(point_file, "CONTOUR\nCLOSE\n%u\n", curve.size());

?
...


You should explicitly cast the return value of 'curve.size()' to some built-in
integral type that is sufficiently large to hold the value, and then use the
format specifier for that type. For example

fprintf(point_file, "CONTOUR\nCLOSE\n%lu\n", (unsigned long) curve.size());
Isn't that rather dangerous? If the return type of curve.size() were to
change, the cast would mask the warning.

Better to find and use the correct format specifier and count your self
lucky your compiler is kind enough to issue that diagnostic.

--
Ian Collins.
Jul 11 '06 #4

P: n/a
Ian Collins wrote:
Andrey Tarasevich wrote:
>>
fprintf(point_file, "CONTOUR\nCLOSE\n%lu\n", (unsigned long) curve.size());
Isn't that rather dangerous? If the return type of curve.size() were to
change, the cast would mask the warning.

Better to find and use the correct format specifier and count your self
lucky your compiler is kind enough to issue that diagnostic.
Note that there is no correct specifier for 'size_t' in C++
(C99 does have one).

If you are suggesting to not cast curve.size() but use a
specifier such as %lu, then what happens if you port to
a system where size_t is different? Silent undefined behaviour.

IMHO it is best to have an implementation-defined result
or a compile error, as Andrey's case will give if size() is
changed to return something else, instead of undefined
behaviour.

Jul 11 '06 #5

P: n/a
In article <11**********************@m73g2000cwd.googlegroups .com>,
ol*****@inspire.net.nz says...

[ ... ]
Note that there is no correct specifier for 'size_t' in C++
(C99 does have one).
TR1 for the C++ library includes all of inttypes.h, stdint.h, etc.

Since we're using C++, why not use an iostream that already knows how
to deal with size_t?

--
Later,
Jerry.

The universe is a figment of its own imagination.
Jul 11 '06 #6

P: n/a
Jerry Coffin wrote:
>
Since we're using C++, why not use an iostream that already knows how
to deal with size_t?
The OP has to write to a FILE* .

He could write the size_t with a stringstream and then write
the string to the FILE*, I suppose.

Jul 11 '06 #7

P: n/a
"asdf" <li*********@gmail.comwrote in message
news:11**********************@b28g2000cwb.googlegr oups.com...
>I got a warning from the following statement:

fprintf(point_file, "CONTOUR\nCLOSE\n%d\n", curve.size());

warning: format '%d' expects type 'int', but argument 3 has type
'size_t'

should I change the coding to

fprintf(point_file, "CONTOUR\nCLOSE\n%u\n", curve.size());

?

Thanks all.
You are most likely using a microsoft compiler. Although size_t is
currently defined as an unsigned int, when you move to a 64 bit compiler it
would change it's size (most likely unsigned long long int or such).

Just about anywhere you use size_t you'll get a warning unless you are
assigning a size_t var to a size_t var.

In your particular case, there is one way to make it safer, although you'll
still get a warning.

std::stringstream ConvStream;
ConvStream << "CONTOUR\nCLOSE\n" << curve.size() << "\n";
fprintf(point_file, ConvStream.str());

The reason this is safer is that when you do switch to a 64 bit compiler
this code will still work without any changes. Your existing code would
have to change the %d to %ld or something, and size_t is unsigned anyway.

Personally, I got tired of _64 bit warnings and disabled them in my compiler
with a project setting.
Jul 12 '06 #8

P: n/a
Jim Langston wrote:
In your particular case, there is one way to make it safer, although you'll
still get a warning.

std::stringstream ConvStream;
ConvStream << "CONTOUR\nCLOSE\n" << curve.size() << "\n";
There would be no warning for that code
fprintf(point_file, ConvStream.str());
fprintf(point_file, ConvStream.str().c_str());

or in fact I would prefer

fprintf(point_file, "%s", ConvStream.str().c_str());
Personally, I got tired of _64 bit warnings and disabled them in my compiler
with a project setting.
Worry about it when the time comes, eh?

Jul 13 '06 #9

P: n/a
"Old Wolf" <ol*****@inspire.net.nzwrote in message
news:11*********************@75g2000cwc.googlegrou ps.com...
Jim Langston wrote:
>In your particular case, there is one way to make it safer, although
you'll
still get a warning.

std::stringstream ConvStream;
ConvStream << "CONTOUR\nCLOSE\n" << curve.size() << "\n";

There would be no warning for that code
It gave me a warning in MS VC++ .net 2003
> fprintf(point_file, ConvStream.str());

fprintf(point_file, ConvStream.str().c_str());

or in fact I would prefer

fprintf(point_file, "%s", ConvStream.str().c_str());
>Personally, I got tired of _64 bit warnings and disabled them in my
compiler
with a project setting.

Worry about it when the time comes, eh?
Well, I was looking at all the warnings, the warnings I was getting was
about storing a SOCKET in an unsigned int which was being used for an ID in
client server. If and when I went to a 64 bit system I would turn warnings
back on, and just change the ID to unsigned long int or whatever it is they
then required for a 64 bit int. Absolutely nothing I can do about it now,
so what good are the warnings?
Jul 13 '06 #10

P: n/a
Jim Langston wrote:
"Old Wolf" <ol*****@inspire.net.nzwrote:
>Jim Langston wrote:
>>>
std::stringstream ConvStream;
ConvStream << "CONTOUR\nCLOSE\n" << curve.size() << "\n";

There would be no warning for that code

It gave me a warning in MS VC++ .net 2003
What is the warning?

Jul 13 '06 #11

P: n/a

"Old Wolf" <ol*****@inspire.net.nzwrote in message
news:11**********************@b28g2000cwb.googlegr oups.com...
Jim Langston wrote:
>"Old Wolf" <ol*****@inspire.net.nzwrote:
>>Jim Langston wrote:

std::stringstream ConvStream;
ConvStream << "CONTOUR\nCLOSE\n" << curve.size() << "\n";

There would be no warning for that code

It gave me a warning in MS VC++ .net 2003

What is the warning?
size_t Value = 10;

std::stringstream Stream;
Stream << Value;

c:\Source\working\console\console.cpp(11) : warning C4267: 'argument' :
conversion from 'size_t' to 'unsigned int', possible loss of data
Jul 14 '06 #12

P: n/a
Jim Langston wrote:
>
size_t Value = 10;

std::stringstream Stream;
Stream << Value;

c:\Source\working\console\console.cpp(11) : warning C4267: 'argument' :
conversion from 'size_t' to 'unsigned int', possible loss of data
Ok. I thought there was a version of std::ostream::operator<<
taking a size_t, but in fact there isn't.

I'm not sure what you would do with a size_t that's bigger than
an unsigned long (or if that is even possible).

Jul 14 '06 #13

P: n/a
"Old Wolf" <ol*****@inspire.net.nzwrote in message
news:11**********************@s13g2000cwa.googlegr oups.com...
Jim Langston wrote:
>>
size_t Value = 10;

std::stringstream Stream;
Stream << Value;

c:\Source\working\console\console.cpp(11) : warning C4267: 'argument' :
conversion from 'size_t' to 'unsigned int', possible loss of data

Ok. I thought there was a version of std::ostream::operator<<
taking a size_t, but in fact there isn't.

I'm not sure what you would do with a size_t that's bigger than
an unsigned long (or if that is even possible).
Well, that's the thing. If this code was switched to a 64 bit system, it
would still work as expected, since at that time they would add a 64 bit
unsigned int to ostream.

The problem comes in when you attempt to store the value in some way, such
as into an unsigned int, that when you switch to a 64 bit compiler it will
break unless you change the unsigned int to a 64 bit int. Using
stringstream, however, it's being converted but not stored.
Jul 14 '06 #14

P: n/a

Old Wolf wrote:
Jim Langston wrote:

size_t Value = 10;

std::stringstream Stream;
Stream << Value;

c:\Source\working\console\console.cpp(11) : warning C4267: 'argument' :
conversion from 'size_t' to 'unsigned int', possible loss of data

Ok. I thought there was a version of std::ostream::operator<<
taking a size_t, but in fact there isn't.
There surely is - look at my other reply.

/Peter
>
I'm not sure what you would do with a size_t that's bigger than
an unsigned long (or if that is even possible).
Jul 14 '06 #15

P: n/a

Jim Langston wrote:
"Old Wolf" <ol*****@inspire.net.nzwrote in message
news:11**********************@b28g2000cwb.googlegr oups.com...
Jim Langston wrote:
"Old Wolf" <ol*****@inspire.net.nzwrote:
Jim Langston wrote:

std::stringstream ConvStream;
ConvStream << "CONTOUR\nCLOSE\n" << curve.size() << "\n";

There would be no warning for that code

It gave me a warning in MS VC++ .net 2003
What is the warning?

size_t Value = 10;

std::stringstream Stream;
Stream << Value;

c:\Source\working\console\console.cpp(11) : warning C4267: 'argument' :
conversion from 'size_t' to 'unsigned int', possible loss of data
This is just a warning from the Microsoft Compiler - and only one that
warns about a portability problem (when porting to 64-bit code).
Furthermore, these warnings are quite unreliable and should not
normally be on. As Microsofts own documentation states:

In this situation, C4267 is caused by a limitation in /Wp64 warnings.
On x86, std::cout<<range_index resolves to the overload of operator<<
that accepts an unsigned int, since size_t is an unsigned int on Win32.
C4267 occurs because you passed a size_t as an unsigned int argument,
which would cause truncation on Win64 where size_t is 64-bit, but
unsigned int is still 32-bit. This can be ignored because if you
compiled for Win64, std::cout<<range_index would resolve to the
overload of operator<< that accepts an unsigned __int64, since that's
what type size_t is on Win64. The 32-bit compiler doesn't notice, so it
warns.

/Peter

Jul 14 '06 #16

P: n/a
peter koch wrote:
Old Wolf wrote:
>Ok. I thought there was a version of std::ostream::operator<<
taking a size_t, but in fact there isn't.

There surely is - look at my other reply.
According to the 1998 version of the standard, the only overloads
for operator<< are: charT, char, signed char, unsigned char,
complex<T>, bool, short, unsigned short, int, unsigned int,
long, unsigned long, float, double, long double, and some pointers.

The standard doesn't appear to say anything about the type
of size_t; in fact, as far as I can see, it doesn't even say that
it has to be an integral type.

17.4.4.7 says:
Unless explicitly stated otherwise, types with distinct names are
distinct types.174)

and the footnote is:
174) An implicit exception to this rule are types described as
synonyms for basic integral types, such as size_t (18.1) and
streamoff (27.4.1).

Although 27.4.1 defines streamoff as being a synonym for an
integral type, 18.1 (or any other section for that matter)
does not describe size_t as being a synonym for anything.

Jul 16 '06 #17

P: n/a
Old Wolf wrote:
peter koch wrote:
>Old Wolf wrote:
>>Ok. I thought there was a version of std::ostream::operator<<
taking a size_t, but in fact there isn't.

There surely is - look at my other reply.

According to the 1998 version of the standard, the only overloads
for operator<< are: charT, char, signed char, unsigned char,
complex<T>, bool, short, unsigned short, int, unsigned int,
long, unsigned long, float, double, long double, and some pointers.

The standard doesn't appear to say anything about the type
of size_t; in fact, as far as I can see, it doesn't even say that
it has to be an integral type.

17.4.4.7 says:
Unless explicitly stated otherwise, types with distinct names are
distinct types.174)

and the footnote is:
174) An implicit exception to this rule are types described as
synonyms for basic integral types, such as size_t (18.1) and
streamoff (27.4.1).

Although 27.4.1 defines streamoff as being a synonym for an
integral type, 18.1 (or any other section for that matter)
does not describe size_t as being a synonym for anything.
The C++ standard says that std::size_t is defined in <cstddef>. Also [18/3]
says that <cstddefprovides the same contents as the C header stddef.h.
Thus, the C++ standard refers to the C standard here. I have no copy of the
C standard, but the draft version provides in [7.17] that size_t is "the
unsigned integer type of the result of the sizeof operator".
Best

Kai-Uwe Bux


Jul 16 '06 #18

P: n/a
In article <11**********************@75g2000cwc.googlegroups. com>,
ol*****@inspire.net.nz says...

[ ... ]
The standard doesn't appear to say anything about the type
of size_t; in fact, as far as I can see, it doesn't even say that
it has to be an integral type.
size_t is defined in cstddef/stddef.h. Section 18.1/3 describes
cstddef as: "The contents are the same as the Standard C library
header <stddef.hwith the following changes:" (and none of the
changes applies to size_t, only to offsetof and NULL).

In the C90 standard, section 7.1.6 says size_t is "the unsigned
integral type of the result of the sizeof operator;"

So, size_t must be a synonym for one of the unsigned integral types
(unsigned char, unsigned short, unsigned int, unsigned long or
possibly "plain" char, if it happens to be unsigned). In C99 and
almost certainly the next version of C++, unsigned long long will be
possible as well, but that type doesn't exist in C++ as it's
currently defined (though many compilers support it anyway).

--
Later,
Jerry.

The universe is a figment of its own imagination.
Jul 17 '06 #19

P: n/a
Jerry Coffin wrote:
ol*****@inspire.net.nz says...
>The standard doesn't appear to say anything about the type
of size_t; in fact, as far as I can see, it doesn't even say that
it has to be an integral type.

size_t is defined in cstddef/stddef.h. Section 18.1/3 describes
cstddef as: "The contents are the same as the Standard C library
header <stddef.hwith the following changes:" (and none of the
changes applies to size_t, only to offsetof and NULL).

In the C90 standard, section 7.1.6 says size_t is "the unsigned
integral type of the result of the sizeof operator;"

So, size_t must be a synonym for one of the unsigned integral types
(unsigned char, unsigned short, unsigned int, unsigned long or
possibly "plain" char, if it happens to be unsigned). In C99 and
almost certainly the next version of C++, unsigned long long will be
possible as well, but that type doesn't exist in C++ as it's
currently defined (though many compilers support it anyway).
In C99, size_t does not have to be a synonym for an
integral type (although it does in C90, as you point out).

Another can of worms for the C++ standards committee :)

Jul 17 '06 #20

P: n/a
In article <11**********************@i42g2000cwa.googlegroups .com>,
ol*****@inspire.net.nz says...

[ ... ]
In C99, size_t does not have to be a synonym for an
integral type (although it does in C90, as you point out).
C99, section 7.17/2 contains almost identical wording to that from
the C90 standard, saying that size_t is: "the unsigned integer type
of the result of the sizeof operator;"

The only difference is that "integral" has been changed to "integer".

There is one fundamental change, however: C99 has the "standard
unsigned integer types", which are basically synonymous with what C90
called the unsigned integer types. It also, however, has the
possibility of "extended unsigned integer types", which are
implementation defined. The "unsigned integer types", are basically a
union of the standard and extended unsigned integer types.

That means in C99, and presumably C++ 0x, size_t might not be a
synonym for any standard type. I guess, in theory, it doesn't
restrict extended unsigned integer types to types that are unsigned
or integers, so (in theory) somebody could define "double" as being
an extended unsigned integer type -- but even as strict as I am about
interpreting the standard only for what it requires and not what it
almost certainly means, it's hard for even me to imagine anybody
defining something as an "extended unsigned integer" unless it truly
is 1) unsigned, and 2) an integer type.

--
Later,
Jerry.

The universe is a figment of its own imagination.
Jul 17 '06 #21

P: n/a
Jerry Coffin wrote:
In article <11**********************@i42g2000cwa.googlegroups .com>,
ol*****@inspire.net.nz says...

[ ... ]
>In C99, size_t does not have to be a synonym for an
integral type (although it does in C90, as you point out).

C99, section 7.17/2 contains almost identical wording to that from
the C90 standard, saying that size_t is: "the unsigned integer type
of the result of the sizeof operator;"

The only difference is that "integral" has been changed to "integer".

There is one fundamental change, however: C99 has the "standard
unsigned integer types", which are basically synonymous with what C90
called the unsigned integer types. It also, however, has the
possibility of "extended unsigned integer types", which are
implementation defined. The "unsigned integer types", are basically a
union of the standard and extended unsigned integer types.

That means in C99, and presumably C++ 0x, size_t might not be a
synonym for any standard type. I guess, in theory, it doesn't
restrict extended unsigned integer types to types that are unsigned
or integers, so (in theory) somebody could define "double" as being
an extended unsigned integer type -- but even as strict as I am about
interpreting the standard only for what it requires and not what it
almost certainly means, it's hard for even me to imagine anybody
defining something as an "extended unsigned integer" unless it truly
is 1) unsigned, and 2) an integer type.
I guess, the interesting question will be whether an implementation will be
required to provide overloaded operators (say for stream output) for those
extended integer types.
Best

Kai-Uwe Bux
Jul 17 '06 #22

P: n/a
Jerry Coffin wrote:
ol*****@inspire.net.nz says...
In C99, size_t does not have to be a synonym for an
integral type (although it does in C90, as you point out).

That means in C99, and presumably C++ 0x, size_t might not be a
synonym for any standard type.
That was my point (clearly it is unsigned and integral).

If C++0x adopts that part of C99, but it does not provide
a specific ostream::operator<< overload for size_t, then
the warning in the original code would actually be valid :)

Jul 17 '06 #23

P: n/a
In article <e9**********@murdoch.acc.Virginia.EDU>,
jk********@gmx.net says...

[ ... ]
I guess, the interesting question will be whether an implementation will be
required to provide overloaded operators (say for stream output) for those
extended integer types.
That, in turn, leads to other interesting questions, such as: if they
do exist, where to they live? Are they part of namespace std, or
should there be some other namespace specifically for implementation
defined extensions? What header do you need to include to get the
declared? Again, should they be along with the standard ones, or in a
special, separate header?

--
Later,
Jerry.

The universe is a figment of its own imagination.
Jul 17 '06 #24

P: n/a
In article <11*********************@s13g2000cwa.googlegroups. com>,
ol*****@inspire.net.nz says...

[ ... ]
That was my point (clearly it is unsigned and integral).
Oh, I wasn't trying to argue against that. Mostly I thought it might
make sense to go into more detail for those less familiar with the
standard, so they might not understand your reasoning (especially,
since the nearly identical wording in the new C standard had been
quoted elsethread, but without any indication about the fact that the
meaning had changed even though the words were essentially
identical).

--
Later,
Jerry.

The universe is a figment of its own imagination.
Jul 17 '06 #25

This discussion thread is closed

Replies have been disabled for this discussion.