Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C Programming > size_t problems

Reply
Thread Tools

size_t problems

 
 
Martin Wells
Guest
Posts: n/a
 
      08-30-2007
Keith Thompson:

> A lot of newbie C programmers will write something like:
>
> int *ptr = malloc(100 * sizeof(int));
>
> and then change it to
>
> int *ptr = (int*)malloc(100 * sizeof(int));
>
> because the compiler warned them about a type mismatch on the
> initialization. In fact, the compiler's warning was correct, and the
> cast merely hides it. The programmer was making one of two mistakes:
> forgetting the required '#include <stdlib.h>', making the compiler
> assume that malloc() returns int, or using a C++ compiler which
> doesn't allow this particular implicit conversion.


While I admire your sentiment as regards following the C89 Standard, I
still must condemn any compiler that allows the "implict function
declaration" feature, not at least without having to explicitly
request it.

compile a.cpp
--ERROR function declaration missing for "malloc".

compile a.cpp -i_want_implicit_function_declarations
--ERROR Type mismatch, "malloc" returns int.

Martin

 
Reply With Quote
 
 
 
 
Keith Thompson
Guest
Posts: n/a
 
      08-30-2007
Martin Wells <(E-Mail Removed)> writes:
> Keith Thompson:
>> A lot of newbie C programmers will write something like:
>>
>> int *ptr = malloc(100 * sizeof(int));
>>
>> and then change it to
>>
>> int *ptr = (int*)malloc(100 * sizeof(int));
>>
>> because the compiler warned them about a type mismatch on the
>> initialization. In fact, the compiler's warning was correct, and the
>> cast merely hides it. The programmer was making one of two mistakes:
>> forgetting the required '#include <stdlib.h>', making the compiler
>> assume that malloc() returns int, or using a C++ compiler which
>> doesn't allow this particular implicit conversion.

>
> While I admire your sentiment as regards following the C89 Standard, I
> still must condemn any compiler that allows the "implict function
> declaration" feature, not at least without having to explicitly
> request it.
>
> compile a.cpp
> --ERROR function declaration missing for "malloc".
>
> compile a.cpp -i_want_implicit_function_declarations
> --ERROR Type mismatch, "malloc" returns int.


As do I -- but our condemnation of such compilers doesn't, alas,
prevent newbies from using them.

--
Keith Thompson (The_Other_Keith) http://www.velocityreviews.com/forums/(E-Mail Removed) <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"
 
Reply With Quote
 
 
 
 
Keith Thompson
Guest
Posts: n/a
 
      08-30-2007
Martin Wells <(E-Mail Removed)> writes:
> Keith Thompson:
>> I'm not saying that you'd necessarily make this particular mistake.
>> But adding a cast to silence a warning should be thought of as a
>> fairly drastic step, and it should be very carefully considered.

>
> I know what you're saying and I agree with you: If you're gonna be
> suppressing warnings through the use of casts then you'd better be
> certain about what you're doing.
>
> Of course though, in the hands of a competant programmer, the use of
> casts to suppress warnings can be quite useful. I've done it quite a
> few times, both in C and in C++. Here might be an example in fully
> portable code:
>
> char NumToDigit(unsigned const x)


I assume this was supposed to be 'unsigned int x'.

> {
> assert( x >= 0 && x <= 9 ); /* Let's assume that we'll never get
> bad input */
>
> return (char)('0' + x); /* No warning, yippee! */
> }


Amusingly, the only warning I got on this was on the assert():

c.c:5: warning: comparison of unsigned expression >= 0 is always true

> A note to those who don't fully understand integer promotion yet:
>
> 1: '0' is promoted to type "unsigned" before it's added to x.
> 2: The result of the addition is put into a char, but we shouldn't get
> a truncation warning because we've explictly used a cast.


I assume the compiler I used can be persuaded to issue such a warning.

Strictly speaking, though, the compiler is just as entitled to issue a
warning with the cast as without it. Most compilers choose not to do
so.

--
Keith Thompson (The_Other_Keith) (E-Mail Removed) <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"
 
Reply With Quote
 
Martin Wells
Guest
Posts: n/a
 
      08-31-2007
Keith Thompson:

> > char NumToDigit(unsigned const x)

>
> I assume this was supposed to be 'unsigned int x'.



No, I meant what I wrote. I'm curious as to why you would've thought
that. . ? Anyway, to explain why I wrote it that way:

1: I invariably use "unsigned" as an abbreviation of "unsigned int".
2: I pretty much use const wherever possible.


> > {
> > assert( x >= 0 && x <= 9 ); /* Let's assume that we'll never get
> > bad input */

>
> > return (char)('0' + x); /* No warning, yippee! */
> > }

>
> Amusingly, the only warning I got on this was on the assert():
>
> c.c:5: warning: comparison of unsigned expression >= 0 is always true



Hehe, I should've copped that Z-)


> > A note to those who don't fully understand integer promotion yet:

>
> > 1: '0' is promoted to type "unsigned" before it's added to x.
> > 2: The result of the addition is put into a char, but we shouldn't get
> > a truncation warning because we've explictly used a cast.

>
> I assume the compiler I used can be persuaded to issue such a warning.
>
> Strictly speaking, though, the compiler is just as entitled to issue a
> warning with the cast as without it. Most compilers choose not to do
> so.



I think C++ has something called "implict_cast" which is used
specifically for telling the compiler to stay quiet, but in C I think
the most common and reliable way is to use a plain ol' vanilla cast.
But yes, you'd be right to say that a compiler can warn about whatever
it wants to warn about.

With the whole "cast to suppress warning" thing, we're relying more on
industry common practice than anything inherent in the C language or
its standard.

Still though, I advocate its usage.

Martin

 
Reply With Quote
 
Martin Wells
Guest
Posts: n/a
 
      08-31-2007
Bill C:

> So why not replace all the strlen() calls with your own function (maybe
> call it i_strlen(), or somesuch name) that returns an int?



Not a bad band-aid at all...

...assuming we don't want to actually clean out the wound and
disinfect it.

Really though that's a good idea if "fixing the code" were out of the
question.

Martin

 
Reply With Quote
 
spacecriter \(Bill C\)
Guest
Posts: n/a
 
      08-31-2007

jacob navia wrote:
> I am trying to compile as much code in 64 bit mode as
> possible to test the 64 bit version of lcc-win.
>
> The problem appears now that size_t is now 64 bits.
>
> Fine. It has to be since there are objects that are more than 4GB
> long.
>
> The problem is, when you have in thousands of places
>
> int s;
>
> // ...
> s = strlen(str) ;
>
> Since strlen returns a size_t, we have a 64 bit result being
> assigned to a 32 bit int.
>
> This can be correct, and in 99.9999999999999999999999999%
> of the cases the string will be smaller than 2GB...
>
> Now the problem:
>
> Since I warn each time a narrowing conversion is done (since
> that could loose data) I end up with hundreds of warnings each time
> a construct like int a = strlen(...) appears. This clutters
> everything, and important warnings go lost.
>
>
> I do not know how to get out of this problem. Maybe any of you has
> a good idea? How do you solve this when porting to 64 bits?
>
> jacob


I assume that you don't want to redefine s as a size_t because it may be
used elsewhere as an int, and you would rather not track down everywhere it
may be used.

So why not replace all the strlen() calls with your own function (maybe
call it i_strlen(), or somesuch name) that returns an int?


--
Bill C.


 
Reply With Quote
 
Keith Thompson
Guest
Posts: n/a
 
      08-31-2007
Martin Wells <(E-Mail Removed)> writes:
> Keith Thompson:
>> > char NumToDigit(unsigned const x)

>>
>> I assume this was supposed to be 'unsigned int x'.

>
> No, I meant what I wrote. I'm curious as to why you would've thought
> that. . ? Anyway, to explain why I wrote it that way:
>
> 1: I invariably use "unsigned" as an abbreviation of "unsigned int".
> 2: I pretty much use const wherever possible.


That was partly a failure on my part to understand what you wrote.
The "unsigned const x" threw me off enough that I momentarily forgot
that "unsigned" is synomymous with "unsigned int". (I probably would
have written "const unsigned int" myself.)

"const" in a parameter declaration doesn't do anything useful for the
caller, since (as I'm sure you know) a function can't modify an
argument anyway. It does prevent the function from (directly)
modifying its own parameter (a local object), but that's of no concern
to the caller.

It would make more sense to be able to specify "const" in the
*definition* of a function but not in the *declaration*. And gcc
seems to allow this:

int foo(int x);

int main(void)
{
return foo(0);
}

int foo(const int x)
{
return x;
}

but I'm not sure whether it's actually legal. In any case, it's not a
style that seems to be common.

I'm sympathetic to the idea uf using const whenever possible.
<OT>If I ever design my own language, declared objects will be
constant (i.e., read-only) by default; if you want to be able to
modify an object, you'll need an extra keyword ('var'?) on the
declaration.</OT>

[...]

> With the whole "cast to suppress warning" thing, we're relying more on
> industry common practice than anything inherent in the C language or
> its standard.
>
> Still though, I advocate its usage.


Fair enough. I don't.

--
Keith Thompson (The_Other_Keith) (E-Mail Removed) <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"
 
Reply With Quote
 
Ian Collins
Guest
Posts: n/a
 
      08-31-2007
Martin Wells wrote:
> Keith Thompson:
>
>> I'm not saying that you'd necessarily make this particular mistake.
>> But adding a cast to silence a warning should be thought of as a
>> fairly drastic step, and it should be very carefully considered.

>
> I know what you're saying and I agree with you: If you're gonna be
> suppressing warnings through the use of casts then you'd better be
> certain about what you're doing.
>
> Of course though, in the hands of a competant programmer, the use of
> casts to suppress warnings can be quite useful. I've done it quite a
> few times, both in C and in C++. Here might be an example in fully
> portable code:
>

If you use casts frequently in C, you are doing something wrong.

If you use naked casts at all in C++, you are doing something very wrong.

In my shops we always have a rule that all casts require a comment, a
good way to make developers think twice before using them.

> char NumToDigit(unsigned const x)
> {
> assert( x >= 0 && x <= 9 ); /* Let's assume that we'll never get
> bad input */
>
> return (char)('0' + x); /* No warning, yippee! */
> }
>

I can't fan a compiler that issues a warning without the cast, just out
of interest, which one does?

--
Ian Collins.
 
Reply With Quote
 
Ben Pfaff
Guest
Posts: n/a
 
      08-31-2007
Martin Wells <(E-Mail Removed)> writes:

> While I admire your sentiment as regards following the C89 Standard, I
> still must condemn any compiler that allows the "implict function
> declaration" feature, not at least without having to explicitly
> request it.


Implicit function declarations are part of C89. A compiler that
rejects programs that use this feature is not an implementation
of C89.
--
"...what folly I commit, I dedicate to you."
--William Shakespeare, _Troilus and Cressida_
 
Reply With Quote
 
CBFalconer
Guest
Posts: n/a
 
      08-31-2007
Keith Thompson wrote:
>

.... snip ...
>
> "const" in a parameter declaration doesn't do anything useful for
> the caller, since (as I'm sure you know) a function can't modify
> an argument anyway. It does prevent the function from (directly)
> modifying its own parameter (a local object), but that's of no
> concern to the caller.


It does if you are passing a pointer to a const item. That way you
can protect the parameter and avoid copying large objects. Such
as, but not limited to, strings.

--
Chuck F (cbfalconer at maineline dot net)
Available for consulting/temporary embedded and systems.
<http://cbfalconer.home.att.net>



--
Posted via a free Usenet account from http://www.teranews.com

 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
reinterpret_cast<std::size_t>(p) and reinterpret_cast<std::size_t&>() Alex Vinokur C++ 1 02-06-2011 07:48 AM
Casting from const pair<const unsigned char*, size_t>* to constpair<unsigned char*, size_t>* Alex Vinokur C++ 9 10-13-2008 05:05 PM
Re: for(size_t a=begin();a!=end();++a){} Chris \( Val \) C++ 2 07-14-2003 06:31 AM
Re: size_t ... standards Howard Hinnant C++ 5 06-30-2003 07:22 PM
Re: size_t ... standards Howard Hinnant C++ 0 06-29-2003 05:45 PM



Advertisments