|
|
size_t problems
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
|
|
0
|
|
|
|
Reply
|
jacob (2538)
|
8/29/2007 7:08:31 PM |
|
"jacob navia" <jacob@jacob.remcomp.fr> wrote in message
news:46d5c46d$0$5108$ba4acef3@news.orange.fr...
>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?
>
There's a very obvious answer to that one. As a compiler-writer, youa re in
a position to do it.
--
Free games and programming goodies.
http://www.personal.leeds.ac.uk/~bgy1mm
|
|
0
|
|
|
|
Reply
|
regniztar (3128)
|
8/29/2007 7:26:00 PM
|
|
jacob navia wrote:
[... "64-bit compiler" with 64-bit size_t ...]
> 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?
Well, some people will probably claim that those hundreds of warnings
are a good thing, as strlen() returns size_t and not int. However,
if you are bombarded with hundreds of such warnings, many people will
simply start ignoring all of the warnings, and the "real" ones will
be lost in the noise.
Perhaps a flag that says "only display the first N instances of this
warning"?
Perhaps you could make int 64 bits as well?
--
+-------------------------+--------------------+-----------------------+
| Kenneth J. Brody | www.hvcomputer.com | #include |
| kenbrody/at\spamcop.net | www.fptech.com | <std_disclaimer.h> |
+-------------------------+--------------------+-----------------------+
Don't e-mail me at: <mailto:ThisIsASpamTrap@gmail.com>
|
|
0
|
|
|
|
Reply
|
kenbrody (1860)
|
8/29/2007 7:33:26 PM
|
|
jacob navia <jacob@jacob.remcomp.fr> writes:
> 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.
I'd suggest fixing the code that does this to use size_t instead
of int. size_t is correct. int is, at best, an approximation to
correct. We've just had a pretty long thread with Malcolm McLean
discussing this very topic; perhaps you should refer to that
thread, if you're not already aware of it.
--
char a[]="\n .CJacehknorstu";int putchar(int);int main(void){unsigned long b[]
={0x67dffdff,0x9aa9aa6a,0xa77ffda9,0x7da6aa6a,0xa67f6aaa,0xaa9aa9f6,0x11f6},*p
=b,i=24;for(;p+=!*p;*p/=4)switch(0[p]&3)case 0:{return 0;for(p--;i--;i--)case+
2:{i++;if(i)break;else default:continue;if(0)case 1:putchar(a[i&15]);break;}}}
|
|
0
|
|
|
|
Reply
|
blp (3953)
|
8/29/2007 7:39:05 PM
|
|
jacob navia <jacob@jacob.remcomp.fr> writes:
> 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?
Why didn't you get the same warnings in 32-bit mode? If int and
size_t are both 32 bits, INT_MAX < SIZE_MAX, and there are values of
size_t that cannot be stored in an int. If the "narrowing conversion"
warning is based on the sizes of the type rather than the ranges, I'd
say you've just discovered a compiler bug.
If you're getting hundreds of warnings, it's because you have hundreds
of instances of potential loss of information.
Note that a conversion to a signed type of a value that doesn't fit in
that type yields an implementation-defined result (or, in C99, raises
an implementation-defined signal). In theory, the result could be
more than just a loss of information.
The problem is to distinguish cases where the conversion can't
actually overflow at execution times from the cases where it can.
Sufficiently clever dataflow analysis in the compiler might eliminate
some of the errors. If, given
int s = strlen(str);
the compiler knows enough about how the value of str that it can be
sure it's no longer than INT_MAX bytes, it can eliminate the warning.
But I don't know if it's practical, or even possible to eliminate
enough of the warnings this way. Doing this in most cases is hard;
doing it in all cases might be equivalent to solving the halting
problem. (That latter is only a guess.)
(Making int 64 bits won't solve the problem, since INT_MAX will still
be less than SIZE_MAX.)
You can filter the compiler's output to eliminate warnings about
narrowing implicit conversions (or, if available, use a compiler
option to turn off that particular warning), but that could miss cases
that could actually overflow.
In my opinion, the warnings are legitimate. The ideal solution is not
to suppress them, but to fix the code, assigning the result of
strlen() to a size_t rather than to an int. (Or I suppose you could
use a cast to shut up the compiler if you're *certain* the result can
never exceed INT_MAX, but that's not what I'd do.)
By compiling the code in 64-bit mode, you've discovered a number of
dormant bugs in the code.
--
Keith Thompson (The_Other_Keith) kst-u@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"
|
|
0
|
|
|
|
Reply
|
kst-u (21474)
|
8/29/2007 7:50:11 PM
|
|
"Malcolm McLean" <regniztar@btinternet.com> writes:
> "jacob navia" <jacob@jacob.remcomp.fr> wrote in message
> news:46d5c46d$0$5108$ba4acef3@news.orange.fr...
[...]
>>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.
[...]
>> 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?
>>
> There's a very obvious answer to that one. As a compiler-writer, youa
> re in a position to do it.
I presume the solution you're suggesting is to make int 64 bits. How
does this help? strlen() still returns size_t, and if int and size_t
are both 64 bits, there will still be size_t values that cannot be
stored in an int.
--
Keith Thompson (The_Other_Keith) kst-u@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"
|
|
0
|
|
|
|
Reply
|
kst-u (21474)
|
8/29/2007 7:51:58 PM
|
|
"Ben Pfaff" <blp@cs.stanford.edu> wrote in message
news:87lkbugmg6.fsf@blp.benpfaff.org...
> I'd suggest fixing the code that does this to use size_t instead
> of int. size_t is correct. int is, at best, an approximation to
> correct. We've just had a pretty long thread with Malcolm McLean
> discussing this very topic; perhaps you should refer to that
> thread, if you're not already aware of it.
>
Yup. As I said, if people would use size_t consistently for every single
calculation that ultimately ends up in an array index there wouldn't be such
a problem. The reality is that people won't, and lots of code doesn't.
--
Free games and programming goodies.
http://www.personal.leeds.ac.uk/~bgy1mm
|
|
0
|
|
|
|
Reply
|
regniztar (3128)
|
8/29/2007 7:52:20 PM
|
|
"Keith Thompson" <kst-u@mib.org> wrote in message
news:lnzm0aw23l.fsf@nuthaus.mib.org...
> "Malcolm McLean" <regniztar@btinternet.com> writes:
>> "jacob navia" <jacob@jacob.remcomp.fr> wrote in message
>> news:46d5c46d$0$5108$ba4acef3@news.orange.fr...
> [...]
>>>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.
> [...]
>
>>> 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?
>>>
>> There's a very obvious answer to that one. As a compiler-writer, youa
>> re in a position to do it.
>
> I presume the solution you're suggesting is to make int 64 bits. How
> does this help? strlen() still returns size_t, and if int and size_t
> are both 64 bits, there will still be size_t values that cannot be
> stored in an int.
>
Yes, but then you'd need an extremely long string to break the code, so the
warning can be suppressed with some confidence that it won't cause a
malfunction.
--
Free games and programming goodies.
http://www.personal.leeds.ac.uk/~bgy1mm
|
|
0
|
|
|
|
Reply
|
regniztar (3128)
|
8/29/2007 8:00:17 PM
|
|
Keith Thompson wrote:
> Why didn't you get the same warnings in 32-bit mode? If int and
> size_t are both 32 bits, INT_MAX < SIZE_MAX, and there are values of
> size_t that cannot be stored in an int. If the "narrowing conversion"
> warning is based on the sizes of the type rather than the ranges, I'd
> say you've just discovered a compiler bug.
>
2GB strings are the most you can get under the windows schema in 32 bits.
> If you're getting hundreds of warnings, it's because you have hundreds
> of instances of potential loss of information.
>
Yes, "*POTENTIALLY*" I could be missing all those strings longer
than 4GB (!!!). But I do not care about those :-)
> Note that a conversion to a signed type of a value that doesn't fit in
> that type yields an implementation-defined result (or, in C99, raises
> an implementation-defined signal). In theory, the result could be
> more than just a loss of information.
>
Only for strings >2GB Keith. Let's keep it realistic!
> The problem is to distinguish cases where the conversion can't
> actually overflow at execution times from the cases where it can.
>
> Sufficiently clever dataflow analysis in the compiler might eliminate
> some of the errors. If, given
> int s = strlen(str);
> the compiler knows enough about how the value of str that it can be
> sure it's no longer than INT_MAX bytes, it can eliminate the warning.
> But I don't know if it's practical, or even possible to eliminate
> enough of the warnings this way. Doing this in most cases is hard;
> doing it in all cases might be equivalent to solving the halting
> problem. (That latter is only a guess.)
>
> (Making int 64 bits won't solve the problem, since INT_MAX will still
> be less than SIZE_MAX.)
>
> You can filter the compiler's output to eliminate warnings about
> narrowing implicit conversions (or, if available, use a compiler
> option to turn off that particular warning), but that could miss cases
> that could actually overflow.
>
> In my opinion, the warnings are legitimate. The ideal solution is not
> to suppress them, but to fix the code, assigning the result of
> strlen() to a size_t rather than to an int. (Or I suppose you could
> use a cast to shut up the compiler if you're *certain* the result can
> never exceed INT_MAX, but that's not what I'd do.)
>
> By compiling the code in 64-bit mode, you've discovered a number of
> dormant bugs in the code.
>
There isn't any string longer than a few K in this program!
Of course is a potential bug, but it is practically impossible!
|
|
0
|
|
|
|
Reply
|
jacob (2538)
|
8/29/2007 8:18:19 PM
|
|
Ben Pfaff wrote:
> jacob navia <jacob@jacob.remcomp.fr> writes:
>
>> 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.
>
> I'd suggest fixing the code that does this to use size_t instead
> of int. size_t is correct. int is, at best, an approximation to
> correct. We've just had a pretty long thread with Malcolm McLean
> discussing this very topic; perhaps you should refer to that
> thread, if you're not already aware of it.
The problem is that if I change those ints into size_t's they
are unsigned, and they will produce problems when comparing them with
signed quantities, making MORE modifications necessary in a cascade
of modifications that would surely introduce bugs...
I have *already* introduced (int)strlen(...) in many places...
|
|
0
|
|
|
|
Reply
|
jacob (2538)
|
8/29/2007 8:20:21 PM
|
|
Malcolm McLean wrote:
>
> "jacob navia" <jacob@jacob.remcomp.fr> wrote in message
> news:46d5c46d$0$5108$ba4acef3@news.orange.fr...
>> 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?
>>
> There's a very obvious answer to that one. As a compiler-writer, youa re
> in a position to do it.
>
???
(Please excuse my stupidity by I do not see it...)
|
|
0
|
|
|
|
Reply
|
jacob (2538)
|
8/29/2007 8:21:15 PM
|
|
On Aug 29, 8:08 pm, jacob navia <ja...@jacob.remcomp.fr> 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?
So the compiler is giving a warning when a 64 bit value is assigned to
a 32 bit variable, but not when a 32 bit unsigned value is assigned to
a 32 bit signed variable.
Well, just because you changed size_t to 64 bits doesn't make strings
any longer. strlen ("hello") still returns 5 and it will fit into an
int just as well as before. So you _could_, possibly as a compiler
option, mark certain functions as returning small(ish) values that
don't require a warning when stored in an int.
But maybe you should look at it from the point of view of a developer
who is switching from a 32 bit to a 64 bit compiler (or most likely
wants to write code that runs fine on a 32 bit and a 64 bit system),
and who _wants_ to fix problems. That programmer would _want_ the
warning and change the variable from int to something else.
Here is the approach that Apple takes: Define two typedefs, Int and
Uint (they actually use different names, but that doesn't matter).
These are used for almost all integer values. On a 32 bit system (32
bit int/long/size_t) they are equal to int/unsigned int, on a 64 bit
system (32 bit int, 64 bit long/size_t) they are equal to long/
unsigned long. Your warning problem goes away. Different types are
used on purpose so that if you mismatch int*/Int* or long*/Int* either
the 32 bit or 64 bit version will give you a compiler error.
Situations where you don't use these types: If you definitely need 64
bit, use long long. If you want to save space, use char/short/int as
suitable.
|
|
0
|
|
|
|
Reply
|
christian.bau1 (402)
|
8/29/2007 8:34:58 PM
|
|
"jacob navia" <jacob@jacob.remcomp.fr> wrote in message
news:46d5d579$0$27386$ba4acef3@news.orange.fr...
> Malcolm McLean wrote:
>> There's a very obvious answer to that one. As a compiler-writer, youa re
>> in a position to do it.
>>
>
> ???
>
> (Please excuse my stupidity by I do not see it...)
>
The campaign for 64 bit ints T-shirts obviously didn't generate enough
publicity. I still have a few left. XXL, one size fits all.
There are some good reasons for not making int 64 bits on a 64 bit machine,
which as a compiler-writer you will be well aware of. However typical
computers are going to have 64 bits of main address space for a very long
time to come, so it makes sense to get the language right now, and keep it
that way for the forseeable future, and not allow decisions to be dominated
by the need to maintain compatibility with legacy 32 bit libraries.
--
Free games and programming goodies.
http://www.personal.leeds.ac.uk/~bgy1mm
|
|
0
|
|
|
|
Reply
|
regniztar (3128)
|
8/29/2007 8:50:18 PM
|
|
On Wed, 29 Aug 2007 20:52:20 +0100, Malcolm McLean wrote:
> "Ben Pfaff" <blp@cs.stanford.edu> wrote in message
> news:87lkbugmg6.fsf@blp.benpfaff.org...
>> I'd suggest fixing the code that does this to use size_t instead
>> of int. size_t is correct. int is, at best, an approximation to
>> correct. We've just had a pretty long thread with Malcolm McLean
>> discussing this very topic; perhaps you should refer to that
>> thread, if you're not already aware of it.
>>
> Yup. As I said, if people would use size_t consistently for every single
> calculation that ultimately ends up in an array index there wouldn't be such
> a problem. The reality is that people won't, and lots of code doesn't.
And lots of people do and lots of code does, and those people don't get
those problems on that code.
Which just goes to show, doing the right thing - using size_t - makes
perfect sense, and ignoring the right thing - as you persist in doing -
makes for problems.
|
|
0
|
|
|
|
Reply
|
kbjarnason (4583)
|
8/29/2007 9:31:13 PM
|
|
On Aug 29, 12:08 pm, jacob navia <ja...@jacob.remcomp.fr> 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?
Make your default int 64 bits, and be done with it.
Ought to be 64 bits on a 64 bit platform anyway.
|
|
0
|
|
|
|
Reply
|
dcorbit (2696)
|
8/29/2007 9:34:37 PM
|
|
On Aug 29, 12:51 pm, Keith Thompson <ks...@mib.org> wrote:
> "Malcolm McLean" <regniz...@btinternet.com> writes:
> > "jacob navia" <ja...@jacob.remcomp.fr> wrote in message
> >news:46d5c46d$0$5108$ba4acef3@news.orange.fr...
> [...]
> >>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.
>
> [...]
>
>
>
>
>
> >> 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?
>
> > There's a very obvious answer to that one. As a compiler-writer, youa
> > re in a position to do it.
>
> I presume the solution you're suggesting is to make int 64 bits. How
> does this help? strlen() still returns size_t, and if int and size_t
> are both 64 bits, there will still be size_t values that cannot be
> stored in an int.
If strlen() returns a number bigger than 9,223,372,036,854,775,808
then there are bigger fish to fry.
Sure, Bill Gates supposedly said that nobody will ever need more than
640K of RAM, and so someday it may be true that strings longer than 9
quintillion bytes are common. But I guess it will be a minor problem
until he can get around to fully correcting the code the right way by
assigning size_t values to the return from strlen() and other things
that return a size_t.
|
|
0
|
|
|
|
Reply
|
dcorbit (2696)
|
8/29/2007 9:38:17 PM
|
|
In article <46d5c46d$0$5108$ba4acef3@news.orange.fr>,
jacob navia <jacob@jacob.remcomp.fr> wrote:
> 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...
Clearly with strlen() the chance of it being an error is negligible.
And I think this is true other size_t->int assignments. For example,
int s = sizeof(whatever) is almost never a problem.
Ideally, I would suggest not generating a warning unless some option
is set for it. (There should always be a "maximally paranoid" option
to help track down obscure errors.) But that only applies to
size_t->int assignments. Other 64->32 assignments may be more likely to be
in error. At the point you generate the warning, can you still tell
that it's a size_t rather than some other 64-bit int type?
-- Richard
--
"Consideration shall be given to the need for as many as 32 characters
in some alphabets" - X3.4, 1963.
|
|
0
|
|
|
|
Reply
|
richard91 (3683)
|
8/29/2007 10:05:41 PM
|
|
"Malcolm McLean" <regniztar@btinternet.com> writes:
> "Keith Thompson" <kst-u@mib.org> wrote in message
> news:lnzm0aw23l.fsf@nuthaus.mib.org...
>> "Malcolm McLean" <regniztar@btinternet.com> writes:
[...]
>>> There's a very obvious answer to that one. As a compiler-writer, youa
>>> re in a position to do it.
>>
>> I presume the solution you're suggesting is to make int 64 bits. How
>> does this help? strlen() still returns size_t, and if int and size_t
>> are both 64 bits, there will still be size_t values that cannot be
>> stored in an int.
>>
> Yes, but then you'd need an extremely long string to break the code,
> so the warning can be suppressed with some confidence that it won't
> cause a malfunction.
That's assuming you're able to suppress the warning for 64-bit
unsigned to 64-bit signed conversions without supressing warnings for,
say, 8-bit unsigned to 8-bit signed conversions. I don't know of any
compiler that allow that kind of find-grained control.
It's better to fix the code. It's even better to write it correctly
in the first place.
--
Keith Thompson (The_Other_Keith) kst-u@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"
|
|
0
|
|
|
|
Reply
|
kst-u (21474)
|
8/29/2007 10:07:34 PM
|
|
In article <1188423277.101634.252870@19g2000hsx.googlegroups.com>,
user923005 <dcorbit@connx.com> wrote:
>Make your default int 64 bits, and be done with it.
>Ought to be 64 bits on a 64 bit platform anyway.
A compiler for an existing operating system needs to fit in with the
system's libraries, so he may not have that choice.
-- Richard
--
"Consideration shall be given to the need for as many as 32 characters
in some alphabets" - X3.4, 1963.
|
|
0
|
|
|
|
Reply
|
richard91 (3683)
|
8/29/2007 10:08:22 PM
|
|
In article <lnhcmivvtl.fsf@nuthaus.mib.org>,
Keith Thompson <kst-u@mib.org> wrote:
>It's better to fix the code. It's even better to write it correctly
>in the first place.
But int s = sizeof(char *) is not broken, even though sizeof() returns
a size_t.
-- Richard
--
"Consideration shall be given to the need for as many as 32 characters
in some alphabets" - X3.4, 1963.
|
|
0
|
|
|
|
Reply
|
richard91 (3683)
|
8/29/2007 10:10:40 PM
|
|
In article <1188426076.465289.294400@22g2000hsm.googlegroups.com>,
user923005 <dcorbit@connx.com> wrote:
>I doubt that the chance a string is longer than 2GB is always
>negligible.
"Always negligible" is irrelevant. Of course it's not negligible in
programs chosen to demonstrate the problem.
>Consider the characters 'C', 'T', 'A', 'G' in various combinations in
>a long sequence of (say) 3 billion.
>That's the human genome.
The chance of a given program being one that stores the complete human
genome in a string is negligible. People with such programs can set the
option I suggested.
-- Richard
--
"Consideration shall be given to the need for as many as 32 characters
in some alphabets" - X3.4, 1963.
|
|
0
|
|
|
|
Reply
|
richard91 (3683)
|
8/29/2007 10:13:50 PM
|
|
On Aug 29, 3:05 pm, rich...@cogsci.ed.ac.uk (Richard Tobin) wrote:
> In article <46d5c46d$0$5108$ba4ac...@news.orange.fr>,
> jacob navia <ja...@jacob.remcomp.fr> wrote:
>
> > 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...
>
> Clearly with strlen() the chance of it being an error is negligible.
> And I think this is true other size_t->int assignments. For example,
> int s = sizeof(whatever) is almost never a problem.
>
> Ideally, I would suggest not generating a warning unless some option
> is set for it. (There should always be a "maximally paranoid" option
> to help track down obscure errors.) But that only applies to
> size_t->int assignments. Other 64->32 assignments may be more likely to be
> in error. At the point you generate the warning, can you still tell
> that it's a size_t rather than some other 64-bit int type?
I doubt that the chance a string is longer than 2GB is always
negligible.
Consider the characters 'C', 'T', 'A', 'G' in various combinations in
a long sequence of (say) 3 billion.
That's the human genome.
The Chrysanthemum genome is much bigger.
I know of people using database systems to do genetics research. The
probability of long character sequences on those systems is not
negligible.
If the machine is capable of handling large data, right away people
will start to do it.
|
|
0
|
|
|
|
Reply
|
dcorbit (2696)
|
8/29/2007 10:21:16 PM
|
|
"Richard Tobin" <richard@cogsci.ed.ac.uk> wrote in message
news:fb4r2u$2uhn$4@pc-news.cogsci.ed.ac.uk...
> The chance of a given program being one that stores the complete human
> genome in a string is negligible. People with such programs can set the
> option I suggested.
>
I work in that field.
Whilst generally you'd want a "rope" type-structure to handle such a long
sequence, there might well be reasons for storing the whole genome as a flat
string. Certainly if I had a 64-bit machine with enough memory installed, I
would expect to have the option, and I'd expect to be able to write the
program in regular C.
--
Free games and programming goodies.
http://www.personal.leeds.ac.uk/~bgy1mm
|
|
0
|
|
|
|
Reply
|
regniztar (3128)
|
8/29/2007 10:35:07 PM
|
|
Richard Tobin wrote:
> In article <1188426076.465289.294400@22g2000hsm.googlegroups.com>,
> user923005 <dcorbit@connx.com> wrote:
>
>> I doubt that the chance a string is longer than 2GB is always
>> negligible.
>
> "Always negligible" is irrelevant. Of course it's not negligible in
> programs chosen to demonstrate the problem.
>
>> Consider the characters 'C', 'T', 'A', 'G' in various combinations in
>> a long sequence of (say) 3 billion.
>> That's the human genome.
>
> The chance of a given program being one that stores the complete human
> genome in a string is negligible. People with such programs can set the
> option I suggested.
>
> -- Richard
The program has strings of at most a few K. It is an IDE (Integrated
development environment, debugger, etc)
An int can hold string lengths of more than 2 billion... MORE than
enough for this environment. This program has been running under 32 bit
windows where all user space is at most 2GB.
|
|
0
|
|
|
|
Reply
|
jacob (2538)
|
8/29/2007 10:44:00 PM
|
|
jacob navia <jacob@jacob.remcomp.fr> writes:
> Keith Thompson wrote:
>> Why didn't you get the same warnings in 32-bit mode? If int and
>> size_t are both 32 bits, INT_MAX < SIZE_MAX, and there are values of
>> size_t that cannot be stored in an int. If the "narrowing conversion"
>> warning is based on the sizes of the type rather than the ranges, I'd
>> say you've just discovered a compiler bug.
>
> 2GB strings are the most you can get under the windows schema in 32 bits.
Ok. Does your compiler know that?
Assigning an arbitrary size_t value to an object of type int, if both
types are 32 bits, could potentially overflow. Your compiler
apparently doesn't issue a warning in that case. Is it because it
knows that the value returned by strlen() can't exceed INT_MAX (if so,
well done, especially since it seems to be smart enough not to make
that assumption on a 64-bit system), or is it because it doesn't issue
a warning when both types are the same size?
For example:
size_t s = func(-1);
/* Assume func() takes a size_t argument and returns it.
Assume func() is defined in another translation unit,
so the compiler can't analyze its definition. In other
words, 's' is initialized to SIZE_MAX, but the compiler
can't make any assumptions about its value. */
signed char c = s;
/* Presumably this produces a warning. */
int i = s;
/* This is a potential overflow. Does this produce
a warning? Should it? */
If your compiler warns about the initialization of 'c' but not about
the initialization of 'i', then IMHO it's being inconsistent. This
doesn't address your original question, but it's related.
[...]
> There isn't any string longer than a few K in this program!
> Of course is a potential bug, but it is practically impossible!
You know that, and I know that, but what matters is what the compiler
knows.
Is it conceivable that a bug in the program and/or some unexpected
input could cause it to create a string longer than 2GB?
You asked how to suppress the bogus warnings without losing any valid
warnings. To do that, your compiler, or some other tool, has to be
able to tell the difference. Telling me that none of the strings are
longer than 2GB doesn't address that concern, unless you can convey
that knowledge to the compiler.
--
Keith Thompson (The_Other_Keith) kst-u@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"
|
|
0
|
|
|
|
Reply
|
kst-u (21474)
|
8/29/2007 10:45:16 PM
|
|
Richard Tobin wrote:
> In article <lnhcmivvtl.fsf@nuthaus.mib.org>,
> Keith Thompson <kst-u@mib.org> wrote:
>
>> It's better to fix the code. It's even better to write it correctly
>> in the first place.
>
> But int s = sizeof(char *) is not broken, even though sizeof() returns
> a size_t.
>
> -- Richard
If we use size_t everywhere, it is an UNSIGNED quantity.
This means that comparisons with signed quantities will provoke
other warnings, etc etc.
int s = strlen(str) is NOT broken.
|
|
0
|
|
|
|
Reply
|
jacob (2538)
|
8/29/2007 10:45:40 PM
|
|
Malcolm McLean wrote:
>
> "Richard Tobin" <richard@cogsci.ed.ac.uk> wrote in message
> news:fb4r2u$2uhn$4@pc-news.cogsci.ed.ac.uk...
>> The chance of a given program being one that stores the complete human
>> genome in a string is negligible. People with such programs can set the
>> option I suggested.
>>
> I work in that field.
> Whilst generally you'd want a "rope" type-structure to handle such a
> long sequence, there might well be reasons for storing the whole genome
> as a flat string. Certainly if I had a 64-bit machine with enough memory
> installed, I would expect to have the option, and I'd expect to be able
> to write the program in regular C.
>
YES SIR!
With my new lcc-win32 YOU WILL BE ABLE TO DO IT!
But I am not speaking of that program. I am speaking about
other programs I am PORTING from 32 bit, whose strings are never
bigger than a few Kbytes at most!
|
|
0
|
|
|
|
Reply
|
jacob (2538)
|
8/29/2007 10:47:25 PM
|
|
"Malcolm McLean" <regniztar@btinternet.com> writes:
> "jacob navia" <jacob@jacob.remcomp.fr> wrote in message
> news:46d5d579$0$27386$ba4acef3@news.orange.fr...
>> Malcolm McLean wrote:
>>> There's a very obvious answer to that one. As a compiler-writer,
>>> youa re in a position to do it.
>>>
>>
>> ???
>>
>> (Please excuse my stupidity by I do not see it...)
>>
> The campaign for 64 bit ints T-shirts obviously didn't generate enough
> publicity. I still have a few left. XXL, one size fits all.
One *shirt* fits all (unless somebody other than you actually wants
one).
> There are some good reasons for not making int 64 bits on a 64 bit
> machine, which as a compiler-writer you will be well aware of. However
> typical computers are going to have 64 bits of main address space for
> a very long time to come, so it makes sense to get the language right
> now, and keep it that way for the forseeable future, and not allow
> decisions to be dominated by the need to maintain compatibility with
> legacy 32 bit libraries.
lcc-win32 (and presumably lcc-win64, if that's what it's called) is a
Windows compiler. jacob does not have the option of changing the
Windows API, and a compiler that's incompatible with the underlying
operating system isn't going to be very useful.
--
Keith Thompson (The_Other_Keith) kst-u@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"
|
|
0
|
|
|
|
Reply
|
kst-u (21474)
|
8/29/2007 10:48:12 PM
|
|
Keith Thompson wrote:
> lcc-win32 (and presumably lcc-win64, if that's what it's called) is a
> Windows compiler. jacob does not have the option of changing the
> Windows API, and a compiler that's incompatible with the underlying
> operating system isn't going to be very useful.
>
Yes. Mr Gates decided that
sizeof(int) == sizeof(long) == 4.
Only long long is 64 bits. PLease address alll flames to him.
NOT TO ME!!!
:-)
|
|
0
|
|
|
|
Reply
|
jacob (2538)
|
8/29/2007 10:49:03 PM
|
|
jacob navia <jacob@jacob.remcomp.fr> writes:
> Richard Tobin wrote:
>> In article <lnhcmivvtl.fsf@nuthaus.mib.org>,
>> Keith Thompson <kst-u@mib.org> wrote:
>>
>>> It's better to fix the code. It's even better to write it correctly
>>> in the first place.
>> But int s = sizeof(char *) is not broken, even though sizeof()
>> returns
>> a size_t.
>
> If we use size_t everywhere, it is an UNSIGNED quantity.
> This means that comparisons with signed quantities will provoke
> other warnings, etc etc.
Perhaps those other signed quantities should have been unsigned as
well.
> int s = strlen(str) is NOT broken.
And yet the compiler you're using warns about it. Perhaps you should
take it up with the author of the compiler.
There may well be no easy way to address your problem. Re-writing all
the code as it should have been written in the first place (using
size_t to hold size_t values) may not be practical. Turning off
warnings that you know aren't necessary, while leaving other warnings
in place, requires conveying that information to the compiler; there
may not be a mechanism for doing so. Inserting hundreds of casts
could suppress the warnings, but I dislike that solution, and it's
still a substantial amount of work.
I suppose you could write a strlen wrapper that calls the real strlen,
checks whether the result exceeds INT_MAX (if you think that check is
worth doing), and then returns the result as an int. That's assuming
strlen calls are the only things triggering the warnings. And you'd
still have to make hundreds of changes in the code.
You know that the conversions aren't going to overflow, but C's type
system doesn't let you convey that knowledge to the compiler.
--
Keith Thompson (The_Other_Keith) kst-u@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"
|
|
0
|
|
|
|
Reply
|
kst-u (21474)
|
8/29/2007 11:26:53 PM
|
|
jacob navia wrote:
>
> Richard Tobin wrote:
> > In article <lnhcmivvtl.fsf@nuthaus.mib.org>,
> > Keith Thompson <kst-u@mib.org> wrote:
> >
> >> It's better to fix the code. It's even better to write it correctly
> >> in the first place.
> >
> > But int s = sizeof(char *) is not broken, even though sizeof() returns
> > a size_t.
> >
> > -- Richard
>
> If we use size_t everywhere, it is an UNSIGNED quantity.
> This means that comparisons with signed quantities will provoke
> other warnings, etc etc.
>
> int s = strlen(str) is NOT broken.
Maybe the signed quantities should be unsigned?
--
pete
|
|
0
|
|
|
|
Reply
|
pfiland (6613)
|
8/29/2007 11:41:59 PM
|
|
jacob navia:
> 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.
<snip>
> 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?
Assuming that you've a shred of intelligence, I'm led to believe that
you suffer from "int syndrome".
"int syndrome" reminds me of old drivers, the kind of people who
always drive the canonical route somewhere. Even during rush-hour,
even at night when the streets are clear, they always take the same
route. I don't know if you'd call it stubbornness or stupidity. They
lack dynamic-ity.
These drivers remind me of the programmers who are "int" people. The
solution to your boggle is so blatantly oblivious that I'm not even
gonna mention what the solution is.
The real problem is why you feel so indoctrinated into using int,
especially places where you shouldn't be using it.
If you want advice though, I'd say use the appropriate types where
appropriate, and to edit any code that uses types wrongly.
Martin
|
|
0
|
|
|
|
Reply
|
warint (199)
|
8/30/2007 12:33:41 AM
|
|
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...
Simply define s as a long long or (better) as a size_t.
--
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
|
|
0
|
|
|
|
Reply
|
cbfalconer (19183)
|
8/30/2007 1:22:59 AM
|
|
jacob navia wrote:
> Keith Thompson wrote:
>
>> Why didn't you get the same warnings in 32-bit mode? If int and
>> size_t are both 32 bits, INT_MAX < SIZE_MAX, and there are values
>> of size_t that cannot be stored in an int. If the "narrowing
>> conversion" warning is based on the sizes of the type rather than
>> the ranges, I'd say you've just discovered a compiler bug.
>
> 2GB strings are the most you can get under the windows schema in 32
> bits.
>
>> If you're getting hundreds of warnings, it's because you have
>> hundreds of instances of potential loss of information.
>
> Yes, "*POTENTIALLY*" I could be missing all those strings longer
> than 4GB (!!!). But I do not care about those :-)
That is precisely the sloppy attitude that has led to many bugs.
--
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
|
|
0
|
|
|
|
Reply
|
cbfalconer (19183)
|
8/30/2007 1:28:56 AM
|
|
jacob navia wrote:
>
.... snip ...
>
> int s = strlen(str) is NOT broken.
Yes it is. How can you guarantee that strlen never returns a value
that exceeds the capacity of an int? However:
size_t s = strlen(str);
is NOT broken, assuming suitable #includes and definitions.
--
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
|
|
0
|
|
|
|
Reply
|
cbfalconer (19183)
|
8/30/2007 2:13:56 AM
|
|
CBFalconer <cbfalconer@yahoo.com> writes:
> jacob navia wrote:
> ... snip ...
>>
>> int s = strlen(str) is NOT broken.
>
> Yes it is. How can you guarantee that strlen never returns a value
> that exceeds the capacity of an int?
By never passing it a pointer to a string longer than INT_MAX
characters. This tends to be easier than, for example, guaranteeing
that 'x + y' will never overflow.
The declaration may or may not be broken, depending on what happens at
run time. The problem is that, apparently, the programmer knows it's
safe, but the compiler doesn't have enough information to prove it.
The ideal solution is to declare s as a size_t, and to make whatever
other code changes follow from that, but that's not always practical.
--
Keith Thompson (The_Other_Keith) kst-u@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"
|
|
0
|
|
|
|
Reply
|
kst-u (21474)
|
8/30/2007 3:45:08 AM
|
|
jacob navia wrote:
> Richard Tobin wrote:
>> In article <lnhcmivvtl.fsf@nuthaus.mib.org>,
>> Keith Thompson <kst-u@mib.org> wrote:
>>
>>> It's better to fix the code. It's even better to write it correctly
>>> in the first place.
>>
>> But int s = sizeof(char *) is not broken, even though sizeof() returns
>> a size_t.
>>
>> -- Richard
>
> If we use size_t everywhere, it is an UNSIGNED quantity.
> This means that comparisons with signed quantities will provoke
> other warnings, etc etc.
>
> int s = strlen(str) is NOT broken.
Why would you want to assign an unsigned value to an int? Why do you
think it makes sense to have a negative size?
--
Ian Collins.
|
|
0
|
|
|
|
Reply
|
ian-news (9881)
|
8/30/2007 3:58:56 AM
|
|
Keith Thompson wrote:
> CBFalconer <cbfalconer@yahoo.com> writes:
>> jacob navia wrote:
>> ... snip ...
>>>
>>> int s = strlen(str) is NOT broken.
>>
>> Yes it is. How can you guarantee that strlen never returns a value
>> that exceeds the capacity of an int?
>
> By never passing it a pointer to a string longer than INT_MAX
> characters. This tends to be easier than, for example, guaranteeing
> that 'x + y' will never overflow.
>
> The declaration may or may not be broken, depending on what happens at
> run time. The problem is that, apparently, the programmer knows it's
> safe, but the compiler doesn't have enough information to prove it.
>
> The ideal solution is to declare s as a size_t, and to make whatever
> other code changes follow from that, but that's not always practical.
Which I said, and you snipped. Why?
--
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
|
|
0
|
|
|
|
Reply
|
cbfalconer (19183)
|
8/30/2007 4:04:16 AM
|
|
Ian Collins wrote:
> jacob navia wrote:
>> Richard Tobin wrote:
>>> In article <lnhcmivvtl.fsf@nuthaus.mib.org>,
>>> Keith Thompson <kst-u@mib.org> wrote:
>>>
>>>> It's better to fix the code. It's even better to write it correctly
>>>> in the first place.
>>> But int s = sizeof(char *) is not broken, even though sizeof() returns
>>> a size_t.
>>>
>>> -- Richard
>> If we use size_t everywhere, it is an UNSIGNED quantity.
>> This means that comparisons with signed quantities will provoke
>> other warnings, etc etc.
>>
>> int s = strlen(str) is NOT broken.
>
> Why would you want to assign an unsigned value to an int? Why do you
> think it makes sense to have a negative size?
>
Because that int is used in many other contexts later, for instance
comparing it with other integers.
int len = strlen(str);
for (i=0; i<len; i++) {
/// etc
}
The i<len comparison would provoke a warning if len is unsigned...
|
|
0
|
|
|
|
Reply
|
jacob (2538)
|
8/30/2007 4:06:08 AM
|
|
Martin Wells wrote:
> jacob navia:
>
>> 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.
> <snip>
>> 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?
>
> Assuming that you've a shred of intelligence, I'm led to believe that
> you suffer from "int syndrome".
>
> "int syndrome" reminds me of old drivers, the kind of people who
> always drive the canonical route somewhere. Even during rush-hour,
> even at night when the streets are clear, they always take the same
> route. I don't know if you'd call it stubbornness or stupidity. They
> lack dynamic-ity.
>
> These drivers remind me of the programmers who are "int" people. The
> solution to your boggle is so blatantly oblivious that I'm not even
> gonna mention what the solution is.
>
> The real problem is why you feel so indoctrinated into using int,
> especially places where you shouldn't be using it.
>
> If you want advice though, I'd say use the appropriate types where
> appropriate, and to edit any code that uses types wrongly.
>
> Martin
>
Assuming that you have a shred of intelligence, you will be able
to understand this:
That int is used in many other contexts later, for instance
comparing it with other integers.
int i,len = strlen(str);
for (i=0; i<len; i++) {
/// etc
}
The i<len comparison would provoke a warning if len is unsigned...
If I make i unsigned too, then its usage within the loop will provoke
even more problems!
|
|
0
|
|
|
|
Reply
|
jacob (2538)
|
8/30/2007 4:09:17 AM
|
|
jacob navia wrote:
> Ian Collins wrote:
>> jacob navia wrote:
>>> Richard Tobin wrote:
>>>> In article <lnhcmivvtl.fsf@nuthaus.mib.org>,
>>>> Keith Thompson <kst-u@mib.org> wrote:
>>>>
>>>>> It's better to fix the code. It's even better to write it correctly
>>>>> in the first place.
>>>> But int s = sizeof(char *) is not broken, even though sizeof() returns
>>>> a size_t.
>>>>
>>>> -- Richard
>>> If we use size_t everywhere, it is an UNSIGNED quantity.
>>> This means that comparisons with signed quantities will provoke
>>> other warnings, etc etc.
>>>
>>> int s = strlen(str) is NOT broken.
>>
>> Why would you want to assign an unsigned value to an int? Why do you
>> think it makes sense to have a negative size?
>>
>
> Because that int is used in many other contexts later, for instance
> comparing it with other integers.
> int len = strlen(str);
>
> for (i=0; i<len; i++) {
> /// etc
> }
>
Why would you want a signed loop index for a zero to unsigned range?
I may sound pedantic, but keeping signed and unsigned quantities apart
avoids nasty bugs.
--
Ian Collins.
|
|
0
|
|
|
|
Reply
|
ian-news (9881)
|
8/30/2007 4:12:57 AM
|
|
Ian Collins said:
> jacob navia wrote:
<snip>
>> int s = strlen(str) is NOT broken.
>
> Why would you want to assign an unsigned value to an int? Why do you
> think it makes sense to have a negative size?
Well, obviously it doesn't make any sense at all, and assigning strlen's
result to an int is clearly wrong; strlen yields size_t, not int.
On the other hand, does it really make sense to play with trolls?
--
Richard Heathfield <http://www.cpax.org.uk>
Email: -www. +rjh@
Google users: <http://www.cpax.org.uk/prg/writings/googly.php>
"Usenet is a strange place" - dmr 29 July 1999
|
|
0
|
|
|
|
Reply
|
rjh (10789)
|
8/30/2007 4:15:02 AM
|
|
jacob navia wrote:
>
> That int is used in many other contexts later, for instance
> comparing it with other integers.
> int i,len = strlen(str);
>
> for (i=0; i<len; i++) {
> /// etc
> }
>
>
> The i<len comparison would provoke a warning if len is unsigned...
>
> If I make i unsigned too, then its usage within the loop will provoke
> even more problems!
Name one.
--
Ian Collins.
|
|
0
|
|
|
|
Reply
|
ian-news (9881)
|
8/30/2007 4:15:07 AM
|
|
Richard Heathfield wrote:
>
> On the other hand, does it really make sense to play with trolls?
>
It beats work...
--
Ian Collins.
|
|
0
|
|
|
|
Reply
|
ian-news (9881)
|
8/30/2007 4:16:38 AM
|
|
Ian Collins wrote:
> Richard Heathfield wrote:
>> On the other hand, does it really make sense to play with trolls?
>>
> It beats work...
>
OK. You win. Will not answer any posts from you.
|
|
0
|
|
|
|
Reply
|
jacob (2538)
|
8/30/2007 4:26:25 AM
|
|
jacob navia wrote:
> Ian Collins wrote:
>> Richard Heathfield wrote:
>>> On the other hand, does it really make sense to play with trolls?
>>>
>> It beats work...
>>
>
> OK. You win. Will not answer any posts from you.
Bad humour day today?
You normally stop once you realise I'm correct...
--
Ian Collins.
|
|
0
|
|
|
|
Reply
|
ian-news (9881)
|
8/30/2007 4:31:33 AM
|
|
jacob navia wrote:
> int s;
>
> // ...
> s = strlen(str) ;
>
> Since strlen returns a size_t, we have a 64 bit result being
> assigned to a 32 bit int.
....
> 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 suggest a warning switch for the 64 bit to 32 bit conversion separate
from warnings for other narrowing conversions.
--
Thad
|
|
0
|
|
|
|
Reply
|
ThadSmith (1279)
|
8/30/2007 4:37:54 AM
|
|
jacob navia <jacob@jacob.remcomp.fr> writes:
> Ian Collins wrote:
>> Why would you want to assign an unsigned value to an int? Why do you
>> think it makes sense to have a negative size?
>
> Because that int is used in many other contexts later, for instance
> comparing it with other integers.
> int len = strlen(str);
>
> for (i=0; i<len; i++) {
> /// etc
> }
>
>
> The i<len comparison would provoke a warning if len is unsigned...
Only if 'i' is declared as type 'int'. If you declare it to have
type 'size_t', you will not have a problem.
--
char a[]="\n .CJacehknorstu";int putchar(int);int main(void){unsigned long b[]
={0x67dffdff,0x9aa9aa6a,0xa77ffda9,0x7da6aa6a,0xa67f6aaa,0xaa9aa9f6,0x11f6},*p
=b,i=24;for(;p+=!*p;*p/=4)switch(0[p]&3)case 0:{return 0;for(p--;i--;i--)case+
2:{i++;if(i)break;else default:continue;if(0)case 1:putchar(a[i&15]);break;}}}
|
|
0
|
|
|
|
Reply
|
blp (3953)
|
8/30/2007 4:39:46 AM
|
|
Ian Collins said:
> jacob navia wrote:
>> Ian Collins wrote:
>>> Richard Heathfield wrote:
>>>> On the other hand, does it really make sense to play with trolls?
>>>>
>>> It beats work...
>>>
>>
>> OK. You win. Will not answer any posts from you.
>
> Bad humour day today?
>
> You normally stop once you realise I'm correct...
Some people's pennies are in orbit.
--
Richard Heathfield <http://www.cpax.org.uk>
Email: -www. +rjh@
Google users: <http://www.cpax.org.uk/prg/writings/googly.php>
"Usenet is a strange place" - dmr 29 July 1999
|
|
0
|
|
|
|
Reply
|
rjh (10789)
|
8/30/2007 6:20:43 AM
|
|
Ben Pfaff wrote:
> jacob navia <jacob@jacob.remcomp.fr> writes:
>
>> Ian Collins wrote:
>>> Why would you want to assign an unsigned value to an int? Why do you
>>> think it makes sense to have a negative size?
>> Because that int is used in many other contexts later, for instance
>> comparing it with other integers.
>> int len = strlen(str);
>>
>> for (i=0; i<len; i++) {
>> /// etc
>> }
>>
>>
>> The i<len comparison would provoke a warning if len is unsigned...
>
> Only if 'i' is declared as type 'int'. If you declare it to have
> type 'size_t', you will not have a problem.
Of course, but that will lead to MORE changes in a chain reaction
that looks quite dangerous...
|
|
0
|
|
|
|
Reply
|
jacob (2538)
|
8/30/2007 6:43:53 AM
|
|
jacob navia <jacob@jacob.remcomp.fr> writes:
> Ben Pfaff wrote:
>> jacob navia <jacob@jacob.remcomp.fr> writes:
>>> Ian Collins wrote:
>>>> Why would you want to assign an unsigned value to an int? Why do you
>>>> think it makes sense to have a negative size?
>>> Because that int is used in many other contexts later, for instance
>>> comparing it with other integers.
>>> int len = strlen(str);
>>>
>>> for (i=0; i<len; i++) {
>>> /// etc
>>> }
>>>
>>>
>>> The i<len comparison would provoke a warning if len is unsigned...
>>
>> Only if 'i' is declared as type 'int'. If you declare it to have
>> type 'size_t', you will not have a problem.
>
> Of course, but that will lead to MORE changes in a chain reaction
> that looks quite dangerous...
It is of course possible to run into problems. If you have code
that you know to work in a given environment, then you may not
want to fix it, because it may break that code in that same
environment if you fail to understand the consequences of the
series of changes. But in this case you're talking about moving
the code to a new environment anyhow (32- to 64-bit), in which
case the code has to be tested anew. The choice is then between
maintaining the old version and the new version separately, as
different pieces of code, or making sure that the fixed version
works in both environments. Most of the time, I'd choose the
latter.
--
char a[]="\n .CJacehknorstu";int putchar(int);int main(void){unsigned long b[]
={0x67dffdff,0x9aa9aa6a,0xa77ffda9,0x7da6aa6a,0xa67f6aaa,0xaa9aa9f6,0x11f6},*p
=b,i=24;for(;p+=!*p;*p/=4)switch(0[p]&3)case 0:{return 0;for(p--;i--;i--)case+
2:{i++;if(i)break;else default:continue;if(0)case 1:putchar(a[i&15]);break;}}}
|
|
0
|
|
|
|
Reply
|
blp (3953)
|
8/30/2007 6:58:37 AM
|
|
Ben Pfaff said:
> jacob navia <jacob@jacob.remcomp.fr> writes:
>
>> Ben Pfaff wrote:
>>> jacob navia <jacob@jacob.remcomp.fr> writes:
<snip>
>>>> The i<len comparison would provoke a warning if len is unsigned...
>>>
>>> Only if 'i' is declared as type 'int'. If you declare it to have
>>> type 'size_t', you will not have a problem.
>>
>> Of course, but that will lead to MORE changes in a chain reaction
>> that looks quite dangerous...
>
> It is of course possible to run into problems.
It is also possible to steer clear of problems. The "chain reaction"
simply doesn't happen if everything has the right type to start off
with. And if it doesn't, the chain reaction is a good thing, not a bad
thing, because it reveals type misconceptions in the code.
--
Richard Heathfield <http://www.cpax.org.uk>
Email: -www. +rjh@
Google users: <http://www.cpax.org.uk/prg/writings/googly.php>
"Usenet is a strange place" - dmr 29 July 1999
|
|
0
|
|
|
|
Reply
|
rjh (10789)
|
8/30/2007 7:10:09 AM
|
|
"jacob navia" <jacob@jacob.remcomp.fr> wrote in message
news:46d6676c$0$27368$ba4acef3@news.orange.fr...
> Ben Pfaff wrote:
>
>> Only if 'i' is declared as type 'int'. If you declare it to have
>> type 'size_t', you will not have a problem.
>
> Of course, but that will lead to MORE changes in a chain reaction
> that looks quite dangerous...
>
Now you are realising the problem.
In fact if you use size_t safely and consistently, virtually all ints need
to be size_t's. The committee have managed to produce a very far-reaching
change to the C language, simply though fixing up a slight problem in the
interface to malloc().
--
Free games and programming goodies.
http://www.personal.leeds.ac.uk/~bgy1mm
|
|
0
|
|
|
|
Reply
|
regniztar (3128)
|
8/30/2007 9:03:50 AM
|
|
CBFalconer <cbfalconer@yahoo.com> writes:
> Keith Thompson wrote:
>> CBFalconer <cbfalconer@yahoo.com> writes:
>>> jacob navia wrote:
>>> ... snip ...
>>>>
>>>> int s = strlen(str) is NOT broken.
>>>
>>> Yes it is. How can you guarantee that strlen never returns a value
>>> that exceeds the capacity of an int?
>>
>> By never passing it a pointer to a string longer than INT_MAX
>> characters. This tends to be easier than, for example, guaranteeing
>> that 'x + y' will never overflow.
>>
>> The declaration may or may not be broken, depending on what happens at
>> run time. The problem is that, apparently, the programmer knows it's
>> safe, but the compiler doesn't have enough information to prove it.
>>
>> The ideal solution is to declare s as a size_t, and to make whatever
>> other code changes follow from that, but that's not always practical.
>
> Which I said, and you snipped. Why?
Sorry, I didn't realize I was repeating some of what you said.
--
Keith Thompson (The_Other_Keith) kst-u@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"
|
|
0
|
|
|
|
Reply
|
kst-u (21474)
|
8/30/2007 9:14:00 AM
|
|
Richard Heathfield <rjh@see.sig.invalid> writes:
> Ben Pfaff said:
>
>> jacob navia <jacob@jacob.remcomp.fr> writes:
>>
>>> Ben Pfaff wrote:
>>>> jacob navia <jacob@jacob.remcomp.fr> writes:
> <snip>
>>>>> The i<len comparison would provoke a warning if len is unsigned...
>>>>
>>>> Only if 'i' is declared as type 'int'. If you declare it to have
>>>> type 'size_t', you will not have a problem.
>>>
>>> Of course, but that will lead to MORE changes in a chain reaction
>>> that looks quite dangerous...
>>
>> It is of course possible to run into problems.
>
> It is also possible to steer clear of problems. The "chain reaction"
> simply doesn't happen if everything has the right type to start off
> with. And if it doesn't, the chain reaction is a good thing, not a bad
> thing, because it reveals type misconceptions in the code.
Ridiculous. Everything doesn't have the "right type" to start
with. Hence the chain reaction.
Millions of programmers the world over use int as a size store for
strings they know to be only a "few bytes" long. It might not be "right"
now, but there is a huge legacy of it.
A chain reaction of this type in a huge legacy code base could cause
all sorts of side effects. You tell the head of QA that moving from int
to size_t will "just work". Not in the real world it doesn't.
|
|
0
|
|
|
|
Reply
|
rgrdev (1814)
|
8/30/2007 9:27:40 AM
|
|
jacob navia wrote:
>
.... snip ...
>
> Because that int is used in many other contexts later, for instance
> comparing it with other integers.
>
> int len = strlen(str);
>
> for (i=0; i<len; i++) {
> /// etc
> }
>
> The i<len comparison would provoke a warning if len is unsigned...
I fail to see any reason why that 'i' should not be declared as
unsigned. Well, maybe extreme laziness.
--
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
|
|
0
|
|
|
|
Reply
|
cbfalconer (19183)
|
8/30/2007 9:29:26 AM
|
|
jacob navia wrote:
> Ben Pfaff wrote:
>> jacob navia <jacob@jacob.remcomp.fr> writes:
>>> Ian Collins wrote:
>>>
>>>> Why would you want to assign an unsigned value to an int? Why
>>>> do you think it makes sense to have a negative size?
>>>
>>> Because that int is used in many other contexts later, for instance
>>> comparing it with other integers.
>>>
>>> int len = strlen(str);
>>>
>>> for (i=0; i<len; i++) {
>>> /// etc
>>> }
>>>
>>> The i<len comparison would provoke a warning if len is unsigned...
>>
>> Only if 'i' is declared as type 'int'. If you declare it to have
>> type 'size_t', you will not have a problem.
>
> Of course, but that will lead to MORE changes in a chain reaction
> that looks quite dangerous...
No, that will eventually lead to more accurate code with fewer
concealed traps. This is C, not B. The fact that you ignore all
these recommendations is a strong indication that your code is not
safe to use.
--
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
|
|
0
|
|
|
|
Reply
|
cbfalconer (19183)
|
8/30/2007 9:34:12 AM
|
|
Richard Heathfield wrote:
> Ian Collins said:
>> jacob navia wrote:
>
> <snip>
>
>>> int s = strlen(str) is NOT broken.
>>
>> Why would you want to assign an unsigned value to an int? Why do
>> you think it makes sense to have a negative size?
>
> Well, obviously it doesn't make any sense at all, and assigning
> strlen's result to an int is clearly wrong; strlen yields size_t,
> not int.
>
> On the other hand, does it really make sense to play with trolls?
Now that is not fair. Yes, Jacob has peculiar (and many are
unsound) ideas, but that does not make him a troll. He seems to
have co-operated on advertising his compiler, for example, without
specifically acknowledgeing so doing.
--
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
|
|
0
|
|
|
|
Reply
|
cbfalconer (19183)
|
8/30/2007 9:40:13 AM
|
|
Richard Heathfield wrote:
> Ian Collins said:
>> jacob navia wrote:
>>> Ian Collins wrote:
>>>> Richard Heathfield wrote:
>>>>
>>>>> On the other hand, does it really make sense to play with trolls?
>>>>>
>>>> It beats work...
>>>>
>>>
>>> OK. You win. Will not answer any posts from you.
>>
>> Bad humour day today?
>>
>> You normally stop once you realise I'm correct...
>
> Some people's pennies are in orbit.
That sounds like a pure Britticism. I suspect a connection with
pay-toilets of bygone days. Is a British penny still roughly one
nautical mile in diameter?
--
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
|
|
0
|
|
|
|
Reply
|
cbfalconer (19183)
|
8/30/2007 9:43:50 AM
|
|
jacob navia wrote:
>
.... snip ...
>
> That int is used in many other contexts later, for instance
> comparing it with other integers.
>
> int i,len = strlen(str);
>
> for (i=0; i<len; i++) {
> /// etc
> }
>
> The i<len comparison would provoke a warning if len is unsigned...
>
> If I make i unsigned too, then its usage within the loop will
> provoke even more problems!
Why? Nothing can create a problem unless you pass its value to an
int, and that value is outside the range that that int can
express. If that happens, lo, you have found a bug. Meanwhile you
have the opportunity to use shift operations on it, to overflow it
without creating unsomething situations, etc.
--
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
|
|
0
|
|
|
|
Reply
|
cbfalconer (19183)
|
8/30/2007 9:49:35 AM
|
|
On Aug 30, 5:12 am, Ian Collins <ian-n...@hotmail.com> wrote:
> jacob navia wrote:
> > Ian Collins wrote:
> >> jacob navia wrote:
> >>> Richard Tobin wrote:
> >>>> In article <lnhcmivvtl....@nuthaus.mib.org>,
> >>>> Keith Thompson <ks...@mib.org> wrote:
>
> >>>>> It's better to fix the code. It's even better to write it correctly
> >>>>> in the first place.
> >>>> But int s = sizeof(char *) is not broken, even though sizeof() returns
> >>>> a size_t.
>
> >>>> -- Richard
> >>> If we use size_t everywhere, it is an UNSIGNED quantity.
> >>> This means that comparisons with signed quantities will provoke
> >>> other warnings, etc etc.
>
> >>> int s = strlen(str) is NOT broken.
>
> >> Why would you want to assign an unsigned value to an int? Why do you
> >> think it makes sense to have a negative size?
>
> > Because that int is used in many other contexts later, for instance
> > comparing it with other integers.
> > int len = strlen(str);
>
> > for (i=0; i<len; i++) {
> > /// etc
> > }
>
> Why would you want a signed loop index for a zero to unsigned range?
>
> I may sound pedantic, but keeping signed and unsigned quantities apart
> avoids nasty bugs.
for (i = strlen (s) - 1; i >= 0; --i) ...
loops through all characters in a string in reverse order, as long as
the length of s is not excessive, if i is a signed 32 bit or longer
integer. Now write that with an unsigned type without any convoluted
code.
|
|
0
|
|
|
|
Reply
|
christian.bau1 (402)
|
8/30/2007 9:55:15 AM
|
|
"christian.bau" <christian.bau@cbau.wanadoo.co.uk> wrote in message
news:1188467715.728131.180650@r29g2000hsg.googlegroups.com...
> On Aug 30, 5:12 am, Ian Collins <ian-n...@hotmail.com> wrote:
>> jacob navia wrote:
>> > Ian Collins wrote:
>> >> jacob navia wrote:
>> >>> Richard Tobin wrote:
>> >>>> In article <lnhcmivvtl....@nuthaus.mib.org>,
>> >>>> Keith Thompson <ks...@mib.org> wrote:
>>
>> >>>>> It's better to fix the code. It's even better to write it
>> >>>>> correctly
>> >>>>> in the first place.
>> >>>> But int s = sizeof(char *) is not broken, even though sizeof()
>> >>>> returns
>> >>>> a size_t.
>>
>> >>>> -- Richard
>> >>> If we use size_t everywhere, it is an UNSIGNED quantity.
>> >>> This means that comparisons with signed quantities will provoke
>> >>> other warnings, etc etc.
>>
>> >>> int s = strlen(str) is NOT broken.
>>
>> >> Why would you want to assign an unsigned value to an int? Why do you
>> >> think it makes sense to have a negative size?
>>
>> > Because that int is used in many other contexts later, for instance
>> > comparing it with other integers.
>> > int len = strlen(str);
>>
>> > for (i=0; i<len; i++) {
>> > /// etc
>> > }
>>
>> Why would you want a signed loop index for a zero to unsigned range?
>>
>> I may sound pedantic, but keeping signed and unsigned quantities apart
>> avoids nasty bugs.
>
> for (i = strlen (s) - 1; i >= 0; --i) ...
>
> loops through all characters in a string in reverse order, as long as
> the length of s is not excessive, if i is a signed 32 bit or longer
> integer. Now write that with an unsigned type without any convoluted
> code.
>
size_t i = strlen(s);
while(i--)
{
/* loop body */
}
--
Free games and programming goodies.
http://www.personal.leeds.ac.uk/~bgy1mm
|
|
0
|
|
|
|
Reply
|
regniztar (3128)
|
8/30/2007 10:04:02 AM
|
|
"christian.bau" wrote:
>
> On Aug 30, 5:12 am, Ian Collins <ian-n...@hotmail.com> wrote:
>
.... snip ...
>
>> I may sound pedantic, but keeping signed and unsigned quantities
>> apart avoids nasty bugs.
>
> for (i = strlen (s) - 1; i >= 0; --i) ...
>
> loops through all characters in a string in reverse order, as long
> as the length of s is not excessive, if i is a signed 32 bit or
> longer integer. Now write that with an unsigned type without any
> convoluted code.
for (i = strlen(s), j = i-1; i; j = i--) {
.... s[j] ....
}
--
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
|
|
0
|
|
|
|
Reply
|
cbfalconer (19183)
|
8/30/2007 10:28:31 AM
|
|
Malcolm McLean wrote:
>
> "christian.bau" <christian.bau@cbau.wanadoo.co.uk>
> wrote in message
> news:1188467715.728131.180650@r29g2000hsg.googlegroups.com...
> > On Aug 30, 5:12 am, Ian Collins <ian-n...@hotmail.com> wrote:
> >> I may sound pedantic,
> >> but keeping signed and unsigned quantities apart
> >> avoids nasty bugs.
> >
> > for (i = strlen (s) - 1; i >= 0; --i) ...
> >
> > loops through all characters in a string in reverse order,
> > as long as the length of s is not excessive,
> > if i is a signed 32 bit or longer integer.
> > Now write that with an unsigned type
> > without any convoluted code.
> >
> size_t i = strlen(s);
> while(i--)
> {
> /* loop body */
> }
Well done!
--
pete
|
|
0
|
|
|
|
Reply
|
pfiland (6613)
|
8/30/2007 10:44:41 AM
|
|
CBFalconer said:
> Richard Heathfield wrote:
>> Ian Collins said:
>>> jacob navia wrote:
>>>> Ian Collins wrote:
>>>>> Richard Heathfield wrote:
>>>>>
>>>>>> On the other hand, does it really make sense to play with trolls?
>>>>>>
>>>>> It beats work...
>>>>>
>>>>
>>>> OK. You win. Will not answer any posts from you.
>>>
>>> Bad humour day today?
>>>
>>> You normally stop once you realise I'm correct...
>>
>> Some people's pennies are in orbit.
>
> That sounds like a pure Britticism.
Well, if you'll pardon the expression, I coined it myself especially for
this thread. And yes, I'm British. So I suppose you're right.
> I suspect a connection with pay-toilets of bygone days.
No, none.
> Is a British penny still roughly one nautical mile in diameter?
No, and it never has been.
--
Richard Heathfield <http://www.cpax.org.uk>
Email: -www. +rjh@
Google users: <http://www.cpax.org.uk/prg/writings/googly.php>
"Usenet is a strange place" - dmr 29 July 1999
|
|
0
|
|
|
|
Reply
|
rjh (10789)
|
8/30/2007 11:11:07 AM
|
|
CBFalconer said:
<snip>
> Yes, Jacob has peculiar (and many are
> unsound) ideas, but that does not make him a troll.
The only alternative I can envisage is that he is utterly brainless. Is
that the theory you prefer?
Look at the facts. We've spent years trying to educate him in the
basics, and failed. If we were unfortunate enough to hire someone like
that, we'd have given him up as a bad job years ago and shuffled him
off into marketing (if we lacked the gumption to sack him outright). We
certainly wouldn't let him anywhere near our compiler-writing division.
--
Richard Heathfield <http://www.cpax.org.uk>
Email: -www. +rjh@
Google users: <http://www.cpax.org.uk/prg/writings/googly.php>
"Usenet is a strange place" - dmr 29 July 1999
|
|
0
|
|
|
|
Reply
|
rjh (10789)
|
8/30/2007 11:14:28 AM
|
|
On 2007-08-30 09:49, CBFalconer <cbfalconer@yahoo.com> wrote:
> jacob navia wrote:
>> That int is used in many other contexts later, for instance
>> comparing it with other integers.
>>
>> int i,len = strlen(str);
>>
>> for (i=0; i<len; i++) {
>> /// etc
>> }
>>
>> The i<len comparison would provoke a warning if len is unsigned...
>>
>> If I make i unsigned too, then its usage within the loop will
>> provoke even more problems!
>
> Why? Nothing can create a problem unless you pass its value to an
> int, and that value is outside the range that that int can
> express.
No. Comparison with signed int also creates problems.
int i = -5;
unsigned u = 5;
if (i > u) printf("Gotcha!\n");
A C programmer should be aware of this when writing code. But if you
change types in existing code, something like that is easy to miss.
Of course Jacob already wrote that his compiler warns about this
problem, so he'll just have to change the type of the next variable or
add a cast.
hp
--
_ | Peter J. Holzer | I know I'd be respectful of a pirate
|_|_) | Sysadmin WSR | with an emu on his shoulder.
| | | hjp@hjp.at |
__/ | http://www.hjp.at/ | -- Sam in "Freefall"
|
|
0
|
|
|
|
Reply
|
hjp-usenet2 (463)
|
8/30/2007 12:23:11 PM
|
|
On 2007-08-29 22:05, Richard Tobin <richard@cogsci.ed.ac.uk> wrote:
> In article <46d5c46d$0$5108$ba4acef3@news.orange.fr>,
> jacob navia <jacob@jacob.remcomp.fr> wrote:
>
>> 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...
>
> Clearly with strlen() the chance of it being an error is negligible.
> And I think this is true other size_t->int assignments. For example,
> int s = sizeof(whatever) is almost never a problem.
Since sizeof(whatever) can be evaluated at compile time (except
when a variable length array is involved), the compiler can even know
exactly when it is a problem.
hp
--
_ | Peter J. Holzer | I know I'd be respectful of a pirate
|_|_) | Sysadmin WSR | with an emu on his shoulder.
| | | hjp@hjp.at |
__/ | http://www.hjp.at/ | -- Sam in "Freefall"
|
|
0
|
|
|
|
Reply
|
hjp-usenet2 (463)
|
8/30/2007 12:43:54 PM
|
|
On 2007-08-29 22:35, Malcolm McLean <regniztar@btinternet.com> wrote:
> "Richard Tobin" <richard@cogsci.ed.ac.uk> wrote in message
> news:fb4r2u$2uhn$4@pc-news.cogsci.ed.ac.uk...
>> The chance of a given program being one that stores the complete human
>> genome in a string is negligible. People with such programs can set the
>> option I suggested.
>>
> I work in that field.
> Whilst generally you'd want a "rope" type-structure to handle such a long
> sequence, there might well be reasons for storing the whole genome as a flat
> string. Certainly if I had a 64-bit machine with enough memory installed, I
> would expect to have the option, and I'd expect to be able to write the
> program in regular C.
Nothing Richard wrote would prevent you from writing your programs in
regular C. All he suggested was that you should be able to turn off the
warning "64 bit value assigned to 32 bit variable" independently from
other "wide value assigned to narrow variable" warnings.
hp
--
_ | Peter J. Holzer | I know I'd be respectful of a pirate
|_|_) | Sysadmin WSR | with an emu on his shoulder.
| | | hjp@hjp.at |
__/ | http://www.hjp.at/ | -- Sam in "Freefall"
|
|
0
|
|
|
|
Reply
|
hjp-usenet2 (463)
|
8/30/2007 12:47:26 PM
|
|
CBFalconer wrote:
> Richard Heathfield wrote:
>> Some people's pennies are in orbit.
>
> That sounds like a pure Britticism.
I suspect after a while you'll understand what RH was referring to, and the
low-value copper coinage will descend.
Phil
--
Philip Potter pgp <at> doc.ic.ac.uk
|
|
0
|
|
|
|
Reply
|
pgp2525 (208)
|
8/30/2007 1:11:34 PM
|
|
Peter J. Holzer said:
<snip>
> Comparison with signed int also creates problems.
>
> int i = -5;
> unsigned u = 5;
> if (i > u) printf("Gotcha!\n");
Indeed. Nevertheless, we must ask why values of two different types are
being compared in this way. Which is greater, half a pound of cheese or
a dozen eggs?
--
Richard Heathfield <http://www.cpax.org.uk>
Email: -www. +rjh@
Google users: <http://www.cpax.org.uk/prg/writings/googly.php>
"Usenet is a strange place" - dmr 29 July 1999
|
|
0
|
|
|
|
Reply
|
rjh (10789)
|
8/30/2007 1:21:01 PM
|
|
Richard Heathfield wrote:
> CBFalconer said:
>
.... snip ...
>
>> Is a British penny still roughly one nautical mile in diameter?
>
> No, and it never has been.
It was when I was last there mumble years ago. Roughly 1 inch
diameter, thick, and two or three in your pocket would tear holes
in the presence of gravity. Much like smoke tests of equipment.
--
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
|
|
0
|
|
|
|
Reply
|
cbfalconer (19183)
|
8/30/2007 1:27:55 PM
|
|
Richard Heathfield wrote:
> CBFalconer said:
>
> <snip>
>
>> Yes, Jacob has peculiar (and many are
>> unsound) ideas, but that does not make him a troll.
>
> The only alternative I can envisage is that he is utterly brainless.
> Is that the theory you prefer?
I'm just dealing with facts. Let him pick the theory under which
he exists around here. Words and actions count.
>
> Look at the facts. We've spent years trying to educate him in the
> basics, and failed. If we were unfortunate enough to hire someone
> like that, we'd have given him up as a bad job years ago and
> shuffled him off into marketing (if we lacked the gumption to sack
> him outright). We certainly wouldn't let him anywhere near our
> compiler-writing division.
Without supervision, yes. This leaves him apparently peculiar.
Maybe he is a big act.
--
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
|
|
0
|
|
|
|
Reply
|
cbfalconer (19183)
|
8/30/2007 1:34:43 PM
|
|
"Peter J. Holzer" wrote:
> CBFalconer <cbfalconer@yahoo.com> wrote:
>> jacob navia wrote:
>>
>>> That int is used in many other contexts later, for instance
>>> comparing it with other integers.
>>>
>>> int i,len = strlen(str);
>>>
>>> for (i=0; i<len; i++) {
>>> /// etc
>>> }
>>>
>>> The i<len comparison would provoke a warning if len is unsigned...
>>>
>>> If I make i unsigned too, then its usage within the loop will
>>> provoke even more problems!
>>
>> Why? Nothing can create a problem unless you pass its value to an
>> int, and that value is outside the range that that int can
>> express.
>
> No. Comparison with signed int also creates problems.
But you don't do that, and if you do the compiler should warn.
Things of different types shouldn't be compared, and is unnecessary
(unless you mis-type variables).
--
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
|
|
0
|
|
|
|
Reply
|
cbfalconer (19183)
|
8/30/2007 1:38:51 PM
|
|
In article <5jmtk1Fc09lU2@mid.individual.net>,
Ian Collins <ian-news@hotmail.com> wrote:
>> int s = strlen(str) is NOT broken.
>Why would you want to assign an unsigned value to an int? Why do you
>think it makes sense to have a negative size?
There are lots of reasons to assign an unsigned value to an int. Most
notably, so that you can do integer arithmetic on it. Do you really
want all array subscript variables to be size_t? If so, you'll have
to consider casting them if, say, you want to subtract one from
another.
-- Richard
--
"Consideration shall be given to the need for as many as 32 characters
in some alphabets" - X3.4, 1963.
|
|
0
|
|
|
|
Reply
|
richard91 (3683)
|
8/30/2007 1:42:14 PM
|
|
"Malcolm McLean" <regniztar@btinternet.com> writes:
> "jacob navia" <jacob@jacob.remcomp.fr> wrote in message
> news:46d6676c$0$27368$ba4acef3@news.orange.fr...
>> Ben Pfaff wrote:
>>
>>> Only if 'i' is declared as type 'int'. If you declare it to have
>>> type 'size_t', you will not have a problem.
>>
>> Of course, but that will lead to MORE changes in a chain reaction
>> that looks quite dangerous...
>>
> Now you are realising the problem.
> In fact if you use size_t safely and consistently, virtually all ints
> need to be size_t's. The committee have managed to produce a very
> far-reaching change to the C language, simply though fixing up a
> slight problem in the interface to malloc().
One last time, maybe? size_t *fixes* a problem. The solution is not
without pain in legacy code, but size_t is _over 17 years old_ now.
You create a problem when you write a book, ostensibly for beginners,
that perpetuates the problems of legacy code! Your excellent post in
an other thread, shows that many of the "problems" with unsigned sizes
are figments (counting down an unsigned value).
You have no solution to offer anyone. 64 bit ints won't wash (for
Jabob Navia's problem) until MS buys the T-shirt, and not doing
anything would have caused just as many, of not more, problems in the
last 18 years. Taking pot-shots and an imperfect solution is one
thing, but you have to come up with something constructive to be taken
seriously.
--
Ben.
|
|
0
|
|
|
|
Reply
|
ben.usenet (6515)
|
8/30/2007 2:37:09 PM
|
|
"Malcolm McLean" <regniztar@btinternet.com> writes:
> In fact if you use size_t safely and consistently, virtually all ints
> need to be size_t's. The committee have managed to produce a very
> far-reaching change to the C language, simply though fixing up a
> slight problem in the interface to malloc().
My code does in fact end up using size_t quite often. If I were
perfectly consistent, it would probably use size_t even more
often. Why is that a problem?
--
Ben Pfaff
http://benpfaff.org
|
|
0
|
|
|
|
Reply
|
blp (3953)
|
8/30/2007 3:16:39 PM
|
|
On Aug 30, 2:21 pm, Richard Heathfield <r...@see.sig.invalid> wrote:
> Peter J. Holzer said:
>
> <snip>
>
> > Comparison with signed int also creates problems.
>
> > int i = -5;
> > unsigned u = 5;
> > if (i > u) printf("Gotcha!\n");
>
> Indeed. Nevertheless, we must ask why values of two different types are
> being compared in this way. Which is greater, half a pound of cheese or
> a dozen eggs?
Not quite the same. If I have a container that can hold 0 to 12 eggs
and another that can hold (use some imagination) -6 to 6 eggs, it's
easy enough to compare say 4 in one with +3 in the other (the first
will make a bigger omelette).
I don't see a problem in comparing 0..12 with -6..6. Of course to
implement such a thing in a machine it may be necessary to do some
conversion first (such as both move sets of eggs to boxes that can
hold -6 to 12).
Bart
|
|
0
|
|
|
|
Reply
|
bc (2211)
|
8/30/2007 3:23:35 PM
|
|
Richard Heathfield <rjh@see.sig.invalid> wrote:
> It is also possible to steer clear of problems. The "chain reaction"
> simply doesn't happen if everything has the right type to start off
> with. And if it doesn't, the chain reaction is a good thing, not a bad
> thing, because it reveals type misconceptions in the code.
Just out of curiosity, what was the rationale behind having strlen()
return size_t instead of "int" or "unsigned int" in the first place?
|
|
0
|
|
|
|
Reply
|
ejensen (115)
|
8/30/2007 4:14:10 PM
|
|
In article <87fy21ay22.fsf@bsb.me.uk>,
Ben Bacarisse <ben.usenet@bsb.me.uk> wrote:
....
>You have no solution to offer anyone. 64 bit ints won't wash (for
>Jabob Navia's problem) until MS buys the T-shirt, and not doing
>anything would have caused just as many, of not more, problems in the
>last 18 years. Taking pot-shots and an imperfect solution is one
>thing, but you have to come up with something constructive to be taken
>seriously.
Like you??? (And Default Loser - both of you just post carp)
|
|
0
|
|
|
|
Reply
|
gazelle2 (1306)
|
8/30/2007 4:24:24 PM
|
|
Richard Tobin wrote:
>
> In article <lnhcmivvtl.fsf@nuthaus.mib.org>,
> Keith Thompson <kst-u@mib.org> wrote:
>
> >It's better to fix the code. It's even better to write it correctly
> >in the first place.
>
> But int s = sizeof(char *) is not broken, even though sizeof() returns
> a size_t.
What happens if sizeof(char *) doesn't fit in an int? (Okay, I don't
expect any real world system to exist for which that is true. But,
does the standard say that sizeof must fit in an int? And if so, why
return a size_t?)
--
+-------------------------+--------------------+-----------------------+
| Kenneth J. Brody | www.hvcomputer.com | #include |
| kenbrody/at\spamcop.net | www.fptech.com | <std_disclaimer.h> |
+-------------------------+--------------------+-----------------------+
Don't e-mail me at: <mailto:ThisIsASpamTrap@gmail.com>
|
|
0
|
|
|
|
Reply
|
kenbrody (1860)
|
8/30/2007 4:37:54 PM
|
|
Bart said:
> If I have a container that can hold 0 to 12 eggs
> and another that can hold (use some imagination) -6 to 6 eggs, it's
> easy enough to compare say 4 in one with +3 in the other (the first
> will make a bigger omelette).
Let's just say I'm suffering from imaginatrophy, shall we? The problem
here is not the negative value itself, but the comparison between a
value of a type that can store negative values and a value of a type
that cannot. These are fundamentally different concepts.
--
Richard Heathfield <http://www.cpax.org.uk>
Email: -www. +rjh@
Google users: <http://www.cpax.org.uk/prg/writings/googly.php>
"Usenet is a strange place" - dmr 29 July 1999
|
|
0
|
|
|
|
Reply
|
rjh (10789)
|
8/30/2007 4:42:11 PM
|
|
Ed Jensen said:
> Richard Heathfield <rjh@see.sig.invalid> wrote:
>> It is also possible to steer clear of problems. The "chain reaction"
>> simply doesn't happen if everything has the right type to start off
>> with. And if it doesn't, the chain reaction is a good thing, not a
>> bad thing, because it reveals type misconceptions in the code.
>
> Just out of curiosity, what was the rationale behind having strlen()
> return size_t instead of "int" or "unsigned int" in the first place?
The Rationale is silent on the matter of strlen (except for a cross-ref
to size_t). The size_t rationale can be found here:
http://www.lysator.liu.se/c/rat/c3.html#3-3-3-4
--
Richard Heathfield <http://www.cpax.org.uk>
Email: -www. +rjh@
Google users: <http://www.cpax.org.uk/prg/writings/googly.php>
"Usenet is a strange place" - dmr 29 July 1999
|
|
0
|
|
|
|
Reply
|
rjh (10789)
|
8/30/2007 4:48:39 PM
|
|
In article <CcCdnQGS-voob0vbnZ2dneKdnZydnZ2d@bt.com>,
Richard Heathfield <rjh@see.sig.invalid> wrote:
>Let's just say I'm suffering from imaginatrophy, shall we? The problem
>here is not the negative value itself, but the comparison between a
>value of a type that can store negative values and a value of a type
>that cannot. These are fundamentally different concepts.
Sizes and array subscripts are naturally connected, and often used
together in expressions. Array subscripts in C can be negative.
strlen() can't return a negative value, but it may make perfect sense
to compare its result with a subscript that can be negative, since it
is the subscript of the nul character at the end of the string.
Suppose s points to some interesting position in the middle of a
string, and s[t] is some other interesting position which may be
before or after s (so t is a signed integer). Why shouldn't I compare
t with strlen(s) to see whether it's before the end of the string?
There would be absolutely no problem using a signed type for sizes if
that type were big enough. Unfortunately, the natural signed type
*isn't* always big enough.
-- Richard
--
"Consideration shall be given to the need for as many as 32 characters
in some alphabets" - X3.4, 1963.
|
|
0
|
|
|
|
Reply
|
richard91 (3683)
|
8/30/2007 4:59:14 PM
|
|
gazelle@xmission.xmission.com (Kenny McCormack) writes:
> both of you just post carp
Fishing for compliments?
--
Ben.
|
|
0
|
|
|
|
Reply
|
ben.usenet (6515)
|
8/30/2007 5:04:03 PM
|
|
>>>>> "RH" == Richard Heathfield <rjh@see.sig.invalid> writes:
RH> Let's just say I'm suffering from imaginatrophy, shall we? The
RH> problem here is not the negative value itself, but the
RH> comparison between a value of a type that can store negative
RH> values and a value of a type that cannot. These are
RH> fundamentally different concepts.
Something I find myself considering frequently: do I have more dollars
in my wallet or in my debit card account? It's impossible for me to
have less than zero dollars in my wallet (although zero is
depressingly frequent), but it's entirely possible, as I have a line
of credit, to have less than zero dollars in my bank account.
The amount of money in my wallet is inherently an unsigned value; the
amount of money in my bank account is inherently a signed value.
Comparisons between them happen several times a week.
Charlton
--
Charlton Wilbur
cwilbur@chromatico.net
|
|
0
|
|
|
|
Reply
|
cwilbur2 (385)
|
8/30/2007 5:08:28 PM
|
|
Ben Bacarisse said:
> gazelle@xmission.xmission.com (Kenny McCormack) writes:
>
>> both of you just post carp
>
> Fishing for compliments?
That comment was out of plaice.
--
Richard Heathfield <http://www.cpax.org.uk>
Email: -www. +rjh@
Google users: <http://www.cpax.org.uk/prg/writings/googly.php>
"Usenet is a strange place" - dmr 29 July 1999
|
|
0
|
|
|
|
Reply
|
rjh (10789)
|
8/30/2007 5:09:28 PM
|
|
Charlton Wilbur said:
>>>>>> "RH" == Richard Heathfield <rjh@see.sig.invalid> writes:
>
> RH> Let's just say I'm suffering from imaginatrophy, shall we? The
> RH> problem here is not the negative value itself, but the
> RH> comparison between a value of a type that can store negative
> RH> values and a value of a type that cannot. These are
> RH> fundamentally different concepts.
>
> Something I find myself considering frequently: do I have more dollars
> in my wallet or in my debit card account? It's impossible for me to
> have less than zero dollars in my wallet (although zero is
> depressingly frequent), but it's entirely possible, as I have a line
> of credit, to have less than zero dollars in my bank account.
But you don't have /any/ dollars in your bank account. What you have is
a number which represents a dollar /balance/ - it is, if you like, the
difference between the number of dollars the bank owes you and the
number of dollars you owe the bank. It can, however, reasonably be
regarded as a monetary amount, and as such can of course be negative.
The number of dollars in your wallet is /also/ a monetary amount, and
monetary amounts can be negative. Of course, the number of dollars in
your wallet cannot be negative, any more than 6 can be negative, even
though 6 is an int and ints can be negative.
--
Richard Heathfield <http://www.cpax.org.uk>
Email: -www. +rjh@
Google users: <http://www.cpax.org.uk/prg/writings/googly.php>
"Usenet is a strange place" - dmr 29 July 1999
|
|
0
|
|
|
|
Reply
|
rjh (10789)
|
8/30/2007 5:17:41 PM
|
|
jacob navia:
> Assuming that you have a shred of intelligence, you will be able
> to understand this:
>
> That int is used in many other contexts later, for instance
> comparing it with other integers.
> int i,len = strlen(str);
>
> for (i=0; i<len; i++) {
> /// etc
>
> }
>
> The i<len comparison would provoke a warning if len is unsigned...
>
> If I make i unsigned too, then its usage within the loop will provoke
> even more problems!
See you're not really looking for a solution at all, but rather a band-
aid to place over the gaping wound.
If you want to trully fix the code, then re-write it PROPERLY.
You might choose "unsigned" over "size_t" if you're EXTREMELY speed-
conscious, even though there'll only be a difference on machines where
"size_t" is bigger than the most efficient integer type. You'll have
to make sure though that the string length will always be within
range. In any way, it should have been written as:
unsigned x = (unsigned)strlen(my_string);
The purpose of the cast would be to suppress a compiler warning.
As for using "int" as a loop counter, I don't see why you'd use a
signed integer type for that purpose (other than "int syndrome" of
course).
Martin
|
|
0
|
|
|
|
Reply
|
warint (199)
|
8/30/2007 5:28:51 PM
|
|
> Millions of programmers the world over use int as a size store for
> strings they know to be only a "few bytes" long. It might not be "right"
> now, but there is a huge legacy of it.
And that's perfectly OK if they make sure the number will never be too
high.
However, they'd want a cast to suppress compiler warnings.
Martin
|
|
0
|
|
|
|
Reply
|
warint (199)
|
8/30/2007 5:31:21 PM
|
|
> You tell the head of QA that moving from int
> to size_t will "just work". Not in the real world it doesn't.
When used properly it works perfectly.
Martin
|
|
0
|
|
|
|
Reply
|
warint (199)
|
8/30/2007 5:32:20 PM
|
|
Martin Wells <warint@eircom.net> writes:
>> You tell the head of QA that moving from int
>> to size_t will "just work". Not in the real world it doesn't.
>
> When used properly it works perfectly.
But that's the problem: if it was used properly, then you
wouldn't have to make the change. The fact that you have to
change it means that related code is likely to make bad related
assumptions.
--
"When I have to rely on inadequacy, I prefer it to be my own."
--Richard Heathfield
|
|
0
|
|
|
|
Reply
|
blp (3953)
|
8/30/2007 5:49:36 PM
|
|
CBFalconer said:
> Richard Heathfield wrote:
>> CBFalconer said:
>>
> ... snip ...
>>
>>> Is a British penny still roughly one nautical mile in diameter?
>>
>> No, and it never has been.
>
> It was when I was last there mumble years ago.
No, it wasn't.
> Roughly 1 inch diameter,
That's a good four orders of magnitude - almost five - away from being a
nautical mile.
--
Richard Heathfield <http://www.cpax.org.uk>
Email: -www. +rjh@
Google users: <http://www.cpax.org.uk/prg/writings/googly.php>
"Usenet is a strange place" - dmr 29 July 1999
|
|
0
|
|
|
|
Reply
|
rjh (10789)
|
8/30/2007 7:04:39 PM
|
|
On Aug 30, 2:40 am, CBFalconer <cbfalco...@yahoo.com> wrote:
> Richard Heathfield wrote:
> > Ian Collins said:
> >> jacob navia wrote:
>
> > <snip>
>
> >>> int s = strlen(str) is NOT broken.
>
> >> Why would you want to assign an unsigned value to an int? Why do
> >> you think it makes sense to have a negative size?
>
> > Well, obviously it doesn't make any sense at all, and assigning
> > strlen's result to an int is clearly wrong; strlen yields size_t,
> > not int.
>
> > On the other hand, does it really make sense to play with trolls?
>
> Now that is not fair. Yes, Jacob has peculiar (and many are
> unsound) ideas, but that does not make him a troll. He seems to
> have co-operated on advertising his compiler, for example, without
> specifically acknowledgeing so doing.
There have been other posters who (over time) became more and more
sensible.
In fact, that should happen to all of us, and it should be an ongoing
process (never coming to completion because none of us are perfect).
Now, I sometimes disagree with Jacob, but I think he makes an honest
attempt to communicate most of the time. Though he may often be
'contrary' I would not label him as a troll.
For my way of thinking, a troll has no interest in information. He
just wants to do something controversial and then sit back and laugh
at the reactions. Either that, or they are mentally ill and are
incapable of intelligent exchange of information. In my opinion,
Jacob Navia is not of either sort.
|
|
0
|
|
|
|
Reply
|
dcorbit (2696)
|
8/30/2007 7:09:07 PM
|
|
On Aug 30, 9:14 am, Ed Jensen <ejen...@visi.com> wrote:
> Richard Heathfield <r...@see.sig.invalid> wrote:
> > It is also possible to steer clear of problems. The "chain reaction"
> > simply doesn't happen if everything has the right type to start off
> > with. And if it doesn't, the chain reaction is a good thing, not a bad
> > thing, because it reveals type misconceptions in the code.
>
> Just out of curiosity, what was the rationale behind having strlen()
> return size_t instead of "int" or "unsigned int" in the first place?
The result of a sizeof () operator is a size_t.
Can you imagine any object which has a negative size?
A size_t can describe the size of any object allowed by the C
language. An int cannot.
What if objects larger than unsigned are allowed by a compiler
implementation?
It is not unlikely that int and unsigned int are 32 bits on some
implementation on 64 bit hardware.
Would you want to be able to allocate an array of 20 GB if you needed
it? In such an instance, an unsigned integer would not work but a
size_t could work.
Can you imagine a better thing to return than a size_t?
Summary:
An int is a defective return from anything that describes the size of
an object.
An unsigned is a defective return from anything that describes the
size of an object.
A size_t is the perfect return from anything that describes the size
of an object.
I try to always use size_t both for object dimentions and array
addressing (though I admit I am not totally rigorous about it).
|
|
0
|
|
|
|
Reply
|
dcorbit (2696)
|
8/30/2007 7:18:15 PM
|
|
Richard Heathfield wrote:
> CBFalconer said:
>
>> Richard Heathfield wrote:
>>> CBFalconer said:
>>>
>> ... snip ...
>>>> Is a British penny still roughly one nautical mile in diameter?
>>> No, and it never has been.
>> It was when I was last there mumble years ago.
>
> No, it wasn't.
>
>> Roughly 1 inch diameter,
>
> That's a good four orders of magnitude - almost five - away from being a
> nautical mile.
>
A nautical mile is a minute of arc of the Earth's great circle. About
6,080 feet or 72,960 inches. That would be a 'Pretty' penny indeed.
--
Joe Wright
"Everything should be made as simple as possible, but not simpler."
--- Albert Einstein ---
|
|
0
|
|
|
|
Reply
|
joewwright (1737)
|
8/30/2007 7:40:19 PM
|
|
In article <46D6F262.7A850299@spamcop.net>,
Kenneth Brody <kenbrody@spamcop.net> wrote:
>What happens if sizeof(char *) doesn't fit in an int?
Then you should get a different computer.
>(Okay, I don't
>expect any real world system to exist for which that is true. But,
>does the standard say that sizeof must fit in an int? And if so, why
>return a size_t?)
No, and it commonly doesn't. But not all programs have to handle
objects that big.
-- Richard
--
"Consideration shall be given to the need for as many as 32 characters
in some alphabets" - X3.4, 1963.
|
|
0
|
|
|
|
Reply
|
richard91 (3683)
|
8/30/2007 8:22:22 PM
|
|
Richard Tobin wrote:
> Ian Collins <ian-news@hotmail.com> wrote:
>
>>> int s = strlen(str) is NOT broken.
>
>> Why would you want to assign an unsigned value to an int? Why
>> do you think it makes sense to have a negative size?
>
> There are lots of reasons to assign an unsigned value to an int.
> Most notably, so that you can do integer arithmetic on it. Do
> you really want all array subscript variables to be size_t? If
> so, you'll have to consider casting them if, say, you want to
> subtract one from another.
Not if you don't get a negative result. You can easily avoid this
by applying the complex test "if (szt1 > szt2) ... else ...".
--
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
|
|
0
|
|
|
|
Reply
|
cbfalconer (19183)
|
8/30/2007 8:25:20 PM
|
|
Richard Heathfield wrote:
> Bart said:
>
>> If I have a container that can hold 0 to 12 eggs and another that
>> can hold (use some imagination) -6 to 6 eggs, it's easy enough to
>> compare say 4 in one with +3 in the other (the first will make a
>> bigger omelette).
>
> Let's just say I'm suffering from imaginatrophy, shall we? The
> problem here is not the negative value itself, but the comparison
> between a value of a type that can store negative values and a value
> of a type that cannot. These are fundamentally different concepts.
However we can compare the "count of items in the bins",
eliminating the dependance on what the items actually are. This
corresponds to casting in some form or another, and carries its own
dangers.
--
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
|
|
0
|
|
|
|
Reply
|
cbfalconer (19183)
|
8/30/2007 8:38:34 PM
|
|
user923005 <dcorbit@connx.com> wrote:
> An int is a defective return from anything that describes the size of
> an object.
And yet, other programming languages get by -- somehow -- by returning
an integer when asked for the length of a string.
> An unsigned is a defective return from anything that describes the
> size of an object.
And yet, other programming languages get by -- somehow -- even though
they don't even have unsigned integer types.
> A size_t is the perfect return from anything that describes the size
> of an object.
I recognize and understand why the range of C types are defined the
way they're defined, but that doesn't minimize the pain when trying to
write 100% portable code.
|
|
0
|
|
|
|
Reply
|
ejensen (115)
|
8/30/2007 9:15:10 PM
|
|
user923005 wrote:
>
.... snip ...
>
> A size_t can describe the size of any object allowed by the C
> language. An int cannot.
In the interests of accuracy, a size_t is guaranteed to describe
those sizes. An int is not guaranteed to have similar capability,
however it may in some systems.
--
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
|
|
0
|
|
|
|
Reply
|
cbfalconer (19183)
|
8/30/2007 10:02:28 PM
|
|
Richard Heathfield wrote:
> CBFalconer said:
>> Richard Heathfield wrote:
>>> CBFalconer said:
>>>
>> ... snip ...
>>>
>>>> Is a British penny still roughly one nautical mile in diameter?
>>>
>>> No, and it never has been.
>>
>> It was when I was last there mumble years ago.
>
> No, it wasn't.
>
>> Roughly 1 inch diameter,
>
> That's a good four orders of magnitude - almost five - away from
> being a nautical mile.
I guess you never heard of mild exageration. :-)
--
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
|
|
0
|
|
|
|
Reply
|
cbfalconer (19183)
|
8/30/2007 10:06:55 PM
|
|
Ed Jensen <ejensen@visi.com> writes:
> user923005 <dcorbit@connx.com> wrote:
>> An int is a defective return from anything that describes the size of
>> an object.
>
> And yet, other programming languages get by -- somehow -- by returning
> an integer when asked for the length of a string.
>
>> An unsigned is a defective return from anything that describes the
>> size of an object.
>
> And yet, other programming languages get by -- somehow -- even though
> they don't even have unsigned integer types.
What programming languages are you thinking of here?
--
"Am I missing something?"
--Dan Pop
|
|
0
|
|
|
|
Reply
|
blp (3953)
|
8/30/2007 10:12:39 PM
|
|
On Aug 30, 2:15 pm, Ed Jensen <ejen...@visi.com> wrote:
> user923005 <dcor...@connx.com> wrote:
> > An int is a defective return from anything that describes the size of
> > an object.
>
> And yet, other programming languages get by -- somehow -- by returning
> an integer when asked for the length of a string.
Can those same languages create objects with a size to large to be
held in an integer?
If 'yes', then those languages are defective. If 'no', then integer
is the correct return.
> > An unsigned is a defective return from anything that describes the
> > size of an object.
>
> And yet, other programming languages get by -- somehow -- even though
> they don't even have unsigned integer types.
I can create a language with a single type. Somehow, I think it will
be less effective than C for programming tasks.
> > A size_t is the perfect return from anything that describes the size
> > of an object.
>
> I recognize and understand why the range of C types are defined the
> way they're defined, but that doesn't minimize the pain when trying to
> write 100% portable code.
The way to minimize the pain of writing 100% portable code is to write
it correctly, according to the language standard. For instance, that
would include using size_t for object sizes. Now, pre-ANSI C did not
have size_t. So that code will require effort to repair.
|
|
0
|
|
|
|
Reply
|
dcorbit (2696)
|
8/30/2007 10:15:40 PM
|
|
On Aug 30, 5:42 pm, Richard Heathfield <r...@see.sig.invalid> wrote:
> Bart said:
>
> > If I have a container that can hold 0 to 12 eggs
> > and another that can hold (use some imagination) -6 to 6 eggs, it's
> > easy enough to compare say 4 in one with +3 in the other (the first
> > will make a bigger omelette).
>
> Let's just say I'm suffering from imaginatrophy, shall we? The problem
> here is not the negative value itself, but the comparison between a
> value of a type that can store negative values and a value of a type
> that cannot. These are fundamentally different concepts.
Possibly, but comparing two such values is still meaningful. Try
adding +6 to the numbers in my little example and both values must now
be positive and can be compared a little more easily. There's still a
question of overflow but that's a different problem.
Signed/unsigned numbers have different ranges. Why is it a big deal to
compare these two types of values? Is it because one type can store a
value that does not exist in the other? That's also a problem with
short and long ints. Anyway the solution can be simple, such as
converting the numbers into a type that accommodates both ranges.
Bart C
|
|
0
|
|
|
|
Reply
|
bc (2211)
|
8/30/2007 10:42:16 PM
|
|
user923005:
> An unsigned is a defective return from anything that describes the
> size of an object.
I don't agree entirely. If:
a) Execution speed is of prime prime prime importance.
b) The value will never be greater than 65536.
, then I wouldn't call it "defective". However I'd use casts wherever
applicable in order to suppress compiler warnings.
Martin
|
|
0
|
|
|
|
Reply
|
warint (199)
|
8/30/2007 10:47:39 PM
|
|
Ed Jensen:
> I recognize and understand why the range of C types are defined the
> way they're defined, but that doesn't minimize the pain when trying to
> write 100% portable code.
It's considerably painless, even fun, if you make it your religion
from the very start.
Martin
|
|
0
|
|
|
|
Reply
|
warint (199)
|
8/30/2007 10:48:33 PM
|
|
Martin Wells <warint@eircom.net> writes:
> user923005:
>> An unsigned is a defective return from anything that describes the
>> size of an object.
>
> I don't agree entirely. If:
>
> a) Execution speed is of prime prime prime importance.
> b) The value will never be greater than 65536.
>
> , then I wouldn't call it "defective". However I'd use casts wherever
> applicable in order to suppress compiler warnings.
Using casts to suppress compiler warnings is widely considered to be a
bad idea. There can be cases, I suppose, where it's necessary, but
what you're really doing is saying to the compiler, "I know exactly
what I'm doing; if you think I'm wrong, please don't tell me". That's
fine if you're right; the problem is when you're wrong (it happens to
all of us), and you've gagged the compiler so it can't tell you.
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.
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.
--
Keith Thompson (The_Other_Keith) kst-u@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"
|
|
0
|
|
|
|
Reply
|
kst-u (21474)
|
8/30/2007 11:02:08 PM
|
|
>>>>> "BP" == Ben Pfaff <blp@cs.stanford.edu> writes:
BP> Ed Jensen <ejensen@visi.com> writes:
>> And yet, other programming languages get by -- somehow -- even
>> though they don't even have unsigned integer types.
BP> What programming languages are you thinking of here?
Perl, where one has to dig into internals to determine whether a
scalar variable is a number or a string and whether a number is an
integer or a floating-point value.
Scheme, where the important distinction is not signed or unsigned, but
exact or inexact.
Those are just two I can think of off the top of my head. I'm sure
there are more.
Charlton
--
Charlton Wilbur
cwilbur@chromatico.net
|
|
0
|
|
|
|
Reply
|
cwilbur2 (385)
|
8/30/2007 11:27:28 PM
|
|
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)
{
assert( x >= 0 && x <= 9 ); /* Let's assume that we'll never get
bad input */
return (char)('0' + x); /* No warning, yippee! */
}
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.
Martin
|
|
0
|
|
|
|
Reply
|
warint (199)
|
8/30/2007 11:39:42 PM
|
|
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
|
|
0
|
|
|
|
Reply
|
warint (199)
|
8/30/2007 11:44:30 PM
|
|
Martin Wells <warint@eircom.net> 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) kst-u@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"
|
|
0
|
|
|
|
Reply
|
kst-u (21474)
|
8/30/2007 11:56:48 PM
|
|
Martin Wells <warint@eircom.net> 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) kst-u@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"
|
|
0
|
|
|
|
Reply
|
kst-u (21474)
|
8/30/2007 11:59:10 PM
|
|
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
|
|
0
|
|
|
|
Reply
|
warint (199)
|
8/31/2007 1:11:04 AM
|
|
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
|
|
0
|
|
|
|
Reply
|
warint (199)
|
8/31/2007 1:12:57 AM
|
|
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.
|
|
0
|
|
|
|
Reply
|
spacecriter (8)
|
8/31/2007 1:36:45 AM
|
|
Martin Wells <warint@eircom.net> 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) kst-u@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"
|
|
0
|
|
|
|
Reply
|
kst-u (21474)
|
8/31/2007 1:53:48 AM
|
|
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.
|
|
0
|
|
|
|
Reply
|
ian-news (9881)
|
8/31/2007 3:58:08 AM
|
|
Martin Wells <warint@eircom.net> 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_
|
|
0
|
|
|
|
Reply
|
blp (3953)
|
8/31/2007 4:32:32 AM
|
|
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
|
|
0
|
|
|
|
Reply
|
cbfalconer (19183)
|
8/31/2007 5:09:07 AM
|
|
CBFalconer wrote:
> 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.
>
Why would you want to? That implies writing something like
void f( const int* const );
which is rather pointless.
simply writing
void f( const int* );
protects the pointed to item. You can change the value of the pointer,
but it still points to constant data.
I'm not sure where "avoid copying large objects" comes form, care to
elaborate?
--
Ian Collins.
|
|
0
|
|
|
|
Reply
|
ian-news (9881)
|
8/31/2007 6:14:20 AM
|
|
Ben Bacarisse <ben.usenet@bsb.me.uk> wrote:
> gazelle@xmission.xmission.com (Kenny McCormack) writes:
>
> > both of you just post carp
>
> Fishing for compliments?
No, Kenny's just trolling again.
Richard
|
|
0
|
|
|
|
Reply
|
rlb (4118)
|
8/31/2007 6:49:46 AM
|
|
rlb@hoekstra-uitgeverij.nl (Richard Bos) writes:
> Ben Bacarisse <ben.usenet@bsb.me.uk> wrote:
>
>> gazelle@xmission.xmission.com (Kenny McCormack) writes:
>>
>> > both of you just post carp
>>
>> Fishing for compliments?
>
> No, Kenny's just trolling again.
>
> Richard
I thing someone missed the joke.
|
|
0
|
|
|
|
Reply
|
rgrdev (1814)
|
8/31/2007 7:01:26 AM
|
|
"Ben Pfaff" <blp@cs.stanford.edu> wrote in message
news:87sl61yrvs.fsf@blp.benpfaff.org...
> "Malcolm McLean" <regniztar@btinternet.com> writes:
>
>> In fact if you use size_t safely and consistently, virtually all ints
>> need to be size_t's. The committee have managed to produce a very
>> far-reaching change to the C language, simply though fixing up a
>> slight problem in the interface to malloc().
>
> My code does in fact end up using size_t quite often. If I were
> perfectly consistent, it would probably use size_t even more
> often. Why is that a problem?
>
If you are indexing an arbitrary-length array, effectively now it is an
error to use int. That's a big change from what most people would recognise
as "C". It is also very undesireable that i, which holds the index, is
described as a "size_t" when it certainly doesn't hold a size. N, the count,
doesn't hold an amount of memory either, but is also a size_t.
Thnen you've got the problem of two standards, in fact 14 standards at last
count, for holding integers. That makes it harder and harder to make
functions fit together. Code is littered with casts because cursorxy takes
two int *s, whilst drawxy takes two size_ts.
The best solution is to to say "int is a type which can index any array"
which means that int must have the same number of bits as a char pointer,
which on 99% of platforms is no problem at all. By making the standard
slightly loose the wierdos can break this rule - if char *'s have an extra
four bits, because underlying bytes are 32 bits, it might be unacceptably
inefficient to have ints large enough to hold them, but the loss of the
ability to index strings taking up an eighth of the address space or more,
without special code, isn't too bad a loss, and the problem won't be solved
by size_t.
There is also the issue of signedness. Again, this is more theoretical than
practical. In practise you can live without the extra bit, because it only a
problem handling
The other problem is backwards compatibility with legacy libraries. However,
as I pointed out, 64 bits of memory will be the maximum for a long time to
come. We mustn't damage C now purely to call a few APIs left over from
32-bit days.
--
Free games and programming goodies.
http://www.personal.leeds.ac.uk/~bgy1mm
|
|
0
|
|
|
|
Reply
|
regniztar (3128)
|
8/31/2007 7:27:15 AM
|
|
Richard <rgrdev@gmail.com> wrote:
> rlb@hoekstra-uitgeverij.nl (Richard Bos) writes:
>
> > Ben Bacarisse <ben.usenet@bsb.me.uk> wrote:
> >
> >> gazelle@xmission.xmission.com (Kenny McCormack) writes:
> >>
> >> > both of you just post carp
> >>
> >> Fishing for compliments?
> >
> > No, Kenny's just trolling again.
>
> I thing someone missed the joke.
Yes, you. Look up the (supposed) etymology of "trolling" in the Jargon
File.
Richard
|
|
0
|
|
|
|
Reply
|
rlb (4118)
|
8/31/2007 7:32:21 AM
|
|
"Richard Heathfield" <rjh@see.sig.invalid> wrote in message
news:J5idnQLYM5aaZkvbnZ2dnUVZ8tHinZ2d@bt.com...
> Charlton Wilbur said:
>
> But you don't have /any/ dollars in your bank account. What you have is
> a number which represents a dollar /balance/ - it is, if you like, the
> difference between the number of dollars the bank owes you and the
> number of dollars you owe the bank. It can, however, reasonably be
> regarded as a monetary amount, and as such can of course be negative.
> The number of dollars in your wallet is /also/ a monetary amount, and
> monetary amounts can be negative. Of course, the number of dollars in
> your wallet cannot be negative, any more than 6 can be negative, even
> though 6 is an int and ints can be negative.
>
It is also possible to have imaginary money, in your paycheck. Happened to
me once.
--
Free games and programming goodies.
http://www.personal.leeds.ac.uk/~bgy1mm
|
|
0
|
|
|
|
Reply
|
regniztar (3128)
|
8/31/2007 7:51:47 AM
|
|
rlb@hoekstra-uitgeverij.nl (Richard Bos) writes:
> Richard <rgrdev@gmail.com> wrote:
>
>> rlb@hoekstra-uitgeverij.nl (Richard Bos) writes:
>>
>> > Ben Bacarisse <ben.usenet@bsb.me.uk> wrote:
>> >
>> >> gazelle@xmission.xmission.com (Kenny McCormack) writes:
>> >>
>> >> > both of you just post carp
>> >>
>> >> Fishing for compliments?
>> >
>> > No, Kenny's just trolling again.
>>
>> I thing someone missed the joke.
>
> Yes, you. Look up the (supposed) etymology of "trolling" in the Jargon
> File.
>
> Richard
But that's not funny.
|
|
0
|
|
|
|
Reply
|
rgrdev (1814)
|
8/31/2007 8:04:40 AM
|
|
Ian Collins wrote:
> CBFalconer wrote:
>> 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.
>
> Why would you want to? That implies writing something like
>
> void f( const int* const );
I think you are confused. "void f(const int* param)" declares param
to be a pointer pointing to a const int (or the first item in a
const array of ints). There is no second const.
However "void f(const struct blah param)" declares param to be an
initialized (and const) copy of something that originated as a
struct blah. The entire struct has been copied into the parameter
space of the function f. This copying is what can be avoided by
using a pointer, as in "void f(const struct blah *param)".
You just can't pass an array by value in C without embedding it in
a suitable struct.
--
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
|
|
0
|
|
|
|
Reply
|
cbfalconer (19183)
|
8/31/2007 9:09:33 AM
|
|
spacecriter (Bill C) wrote:
> 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?
>
>
That would be a good solution!
THANKS!
jacob
|
|
0
|
|
|
|
Reply
|
jacob (2538)
|
8/31/2007 9:16:10 AM
|
|
jacob navia <jacob@jacob.remcomp.fr> writes:
> spacecriter (Bill C) wrote:
>> So why not replace all the strlen() calls with your own function (maybe
>> call it i_strlen(), or somesuch name) that returns an int?
>>
>>
> That would be a good solution!
>
> THANKS!
>
> jacob
You can call it "littlestrlen()" ....
|
|
0
|
|
|
|
Reply
|
rgrdev (1814)
|
8/31/2007 9:27:15 AM
|
|
CBFalconer <cbfalconer@yahoo.com> writes:
> 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.
I was referring only to applying 'const' to the parameter itself. (I
could have been clearer.)
--
Keith Thompson (The_Other_Keith) kst-u@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"
|
|
0
|
|
|
|
Reply
|
kst-u (21474)
|
8/31/2007 9:50:09 AM
|
|
CBFalconer wrote:
> Ian Collins wrote:
>> CBFalconer wrote:
>>> 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.
>> Why would you want to? That implies writing something like
>>
>> void f( const int* const );
>
> I think you are confused. "void f(const int* param)" declares param
> to be a pointer pointing to a const int (or the first item in a
> const array of ints). There is no second const.
>
Confused by what you wrote maybe? "That way you can protect the
parameter" the only way you can prevent the parameter being modified is
to make the parameter const. I (and I think Keith) was pointing out
that making the parameter type const is seldom, if ever, useful.
--
Ian Collins.
|
|
0
|
|
|
|
Reply
|
ian-news (9881)
|
8/31/2007 9:58:45 AM
|
|
Malcolm McLean said:
<snip>
> If you are indexing an arbitrary-length array, effectively now it is
> an error to use int.
Yes.
> That's a big change from what most people would recognise as "C".
No. It's the way I've been using C ever since I learned how to do it
properly, rather than follow the Schildt-style advice I had received up
to that point.
> It is also very undesireable that i, which holds the
> index, is described as a "size_t" when it certainly doesn't hold a
> size.
I'll agree that an index doesn't hold a size...
> N, the count, doesn't hold an amount of memory either, but is
> also a size_t.
....but I can't agree that it doesn't hold a count.
> Thnen you've got the problem of two standards, in fact 14 standards at
> last count, for holding integers.
The integer types that C90 must support (and which are required to be
integer types) are char, signed char, unsigned char, short, unsigned
short, int, unsigned int, long, unsigned long, wchar_t, size_t,
ptrdiff_t, sig_atomic_t - which is thirteen.
C99 adds long long and unsigned long long, making at least fifteen, and
then there are an indeterminate number of intsuch-and-such_t types,
making a count impractical.
Either way, your count, like your argument, is wrong.
> That makes it harder and harder to
> make functions fit together.
No, it doesn't.
> Code is littered with casts because
> cursorxy takes two int *s, whilst drawxy takes two size_ts.
The only code that is littered with casts is broken code.
> The best solution is to to say "int is a type which can index any
> array" which means that int must have the same number of bits as a
> char pointer, which on 99% of platforms is no problem at all.
No, the best solution is to use size_t where appropriate, and int where
appropriate.
<snip>
> The other problem is backwards compatibility with legacy libraries.
Not a problem at all. All you have to do is recompile the library with
the new compiler. If that breaks the library, it probably wasn't a very
good library anyway.
> However, as I pointed out, 64 bits of memory will be the maximum for a
> long time to come.
Ha. And perhaps ha.
> We mustn't damage C now purely to call a few APIs left over from
> 32-bit days.
C has never /had/ 32-bit days. C doesn't care how many bits a byte or an
int or a size_t or an address bus has, subject to certain basic minima
which are considerably lower than 32. Write your code to depend on
64-bit ints, and you can bet your bottom dollar it'll break one day,
and you'll be resisting the change to 128 or 256 or whatever it is out
of sheer fear of breakage. That's your problem. The solution? Stop
depending on particular sizes, and work out how to program in the
large.
--
Richard Heathfield <http://www.cpax.org.uk>
Email: -www. +rjh@
Google users: <http://www.cpax.org.uk/prg/writings/googly.php>
"Usenet is a strange place" - dmr 29 July 1999
|
|
0
|
|
|
|
Reply
|
rjh (10789)
|
8/31/2007 10:02:12 AM
|
|
jacob navia wrote:
> spacecriter (Bill C) wrote:
>> jacob navia wrote:
>>
.... snip ...
>>
>> 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?
>
> That would be a good solution!
No, that would be a temporary glossing over, avoiding fixing the
fundamental problem, and postponing the fix (or abandonment) until
later, with attendant confusion of the code. Not wise in the long
term. Some things are better done right.
--
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
|
|
0
|
|
|
|
Reply
|
cbfalconer (19183)
|
8/31/2007 10:02:31 AM
|
|
jacob navia <jacob@jacob.remcomp.fr> writes:
> spacecriter (Bill C) wrote:
>> 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?
>>
> That would be a good solution!
>
> THANKS!
Hmm, sounds familiar.
| I suppose you could write a strlen wrapper that calls the real strlen,
| checks whether the result exceeds INT_MAX (if you think that check is
| worth doing), and then returns the result as an int. That's assuming
| strlen calls are the only things triggering the warnings. And you'd
| still have to make hundreds of changes in the code.
<http://groups.google.com/group/comp.lang.c/msg/3ef33439c43be6ac>
--
Keith Thompson (The_Other_Keith) kst-u@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"
|
|
0
|
|
|
|
Reply
|
kst-u (21474)
|
8/31/2007 10:12:50 AM
|
|
"Malcolm McLean" <regniztar@btinternet.com> writes:
[...]
> If you are indexing an arbitrary-length array, effectively now it is
> an error to use int. That's a big change from what most people would
> recognise as "C".
The "big change" was made in 1989.
> It is also very undesireable that i, which holds the
> index, is described as a "size_t" when it certainly doesn't hold a
> size. N, the count, doesn't hold an amount of memory either, but is
> also a size_t.
Then you should add this to your code:
typedef size_t size_or_count_or_index_t;
Or just think of size_t as something more general than its name
implies.
> Thnen you've got the problem of two standards, in fact 14 standards at
> last count, for holding integers. That makes it harder and harder to
> make functions fit together. Code is littered with casts because
> cursorxy takes two int *s, whilst drawxy takes two size_ts.
They're called "types", not "standards".
I actually tend to think that the number of standard types in C has
gotten to be a bit much. It's probably inevitable given the way C has
evolved, but it's something I'd do differently if I were designing a
new language from scratch. Rather than having a dozen or so
predefined integer types, I think I'd prefer a general method to
define types.
We wouldn't tolerate a language with just a dozen or so predefined
array types, each with a fixed length that varies from one
implementation to another, but we accept it for integer types. (And
yes, there are reasons for the difference.)
But this is just idle speculation. C is what it is.
--
Keith Thompson (The_Other_Keith) kst-u@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"
|
|
0
|
|
|
|
Reply
|
kst-u (21474)
|
8/31/2007 10:35:45 AM
|
|
In article <46d7f116$0$25954$ba4acef3@news.orange.fr>,
jacob navia <jacob@jacob.remcomp.fr> wrote:
>#define strlen Strlen_i;
These is probably not legal, at least in theory. Doing it after all
includes will probably work, though.
-- Richard
--
"Consideration shall be given to the need for as many as 32 characters
in some alphabets" - X3.4, 1963.
|
|
0
|
|
|
|
Reply
|
richard91 (3683)
|
8/31/2007 10:36:30 AM
|
|
CBFalconer <cbfalconer@yahoo.com> writes:
> jacob navia wrote:
>> spacecriter (Bill C) wrote:
>>> jacob navia wrote:
>>>
> ... snip ...
>>>
>>> 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?
>>
>> That would be a good solution!
>
> No, that would be a temporary glossing over, avoiding fixing the
> fundamental problem, and postponing the fix (or abandonment) until
> later, with attendant confusion of the code. Not wise in the long
> term. Some things are better done right.
If he can be certain that none of the strings he's dealing with will
ever exceed 32767 bytes (say, they're people's names), then it's not a
horribly bad solution, especially if his wrapper invokes the real
strlen() and checks the result before returning it as an int.
--
Keith Thompson (The_Other_Keith) kst-u@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"
|
|
0
|
|
|
|
Reply
|
kst-u (21474)
|
8/31/2007 10:41:20 AM
|
|
Keith Thompson wrote:
> jacob navia <jacob@jacob.remcomp.fr> writes:
>> spacecriter (Bill C) wrote:
>>> 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?
>>>
>> That would be a good solution!
>>
>> THANKS!
>
> Hmm, sounds familiar.
>
> | I suppose you could write a strlen wrapper that calls the real strlen,
> | checks whether the result exceeds INT_MAX (if you think that check is
> | worth doing), and then returns the result as an int. That's assuming
> | strlen calls are the only things triggering the warnings. And you'd
> | still have to make hundreds of changes in the code.
>
NO!
Just
int Strlen_i(char *s)
{
char *start=s;
while (*s)
s++;
return s-start;
}
#define strlen Strlen_i;
> <http://groups.google.com/group/comp.lang.c/msg/3ef33439c43be6ac>
>
|
|
0
|
|
|
|
Reply
|
jacob (2538)
|
8/31/2007 10:44:23 AM
|
|
jacob navia <jacob@jacob.remcomp.fr> writes:
> Keith Thompson wrote:
>> jacob navia <jacob@jacob.remcomp.fr> writes:
>>> spacecriter (Bill C) wrote:
>>>> 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?
>>>>
>>> That would be a good solution!
>>>
>>> THANKS!
>>
>> Hmm, sounds familiar.
>>
>> | I suppose you could write a strlen wrapper that calls the real strlen,
>> | checks whether the result exceeds INT_MAX (if you think that check is
>> | worth doing), and then returns the result as an int. That's assuming
>> | strlen calls are the only things triggering the warnings. And you'd
>> | still have to make hundreds of changes in the code.
>>
>
> NO!
>
> Just
>
> int Strlen_i(char *s)
> {
> char *start=s;
> while (*s)
> s++;
> return s-start;
> }
> #define strlen Strlen_i;
int Strlen_i(char *s)
{
int i=0;
while (*s++ && ++i);
return i;
}
why? It returns in the case of a mad string (ie bigger than int) when i
wraps to 0. Assuming i does that in the standard.
|
|
0
|
|
|
|
Reply
|
rgrdev (1814)
|
8/31/2007 11:03:02 AM
|
|
In article <j3k5rct195.fsf@homelinux.net>, Richard <rgrdev@gmail.com> wrote:
>why? It returns in the case of a mad string (ie bigger than int) when i
>wraps to 0. Assuming i does that in the standard.
Integer overflow is allowed to be an error. But on most systems, huge
positive integers wrap around to huge negative ones and only get to
zero again when they are doubly huge.
-- Richard
--
"Consideration shall be given to the need for as many as 32 characters
in some alphabets" - X3.4, 1963.
|
|
0
|
|
|
|
Reply
|
richard91 (3683)
|
8/31/2007 11:04:45 AM
|
|
In article <46d7b9fd.88470610@news.xs4all.nl>,
Richard Bos <rlb@hoekstra-uitgeverij.nl> wrote:
>Ben Bacarisse <ben.usenet@bsb.me.uk> wrote:
>
>> gazelle@xmission.xmission.com (Kenny McCormack) writes:
>>
>> > both of you just post carp
>>
>> Fishing for compliments?
>
>No, Ben's just trolling again.
>
>Richard
It was an intentional play on words (double entendre).
|
|
0
|
|
|
|
Reply
|
gazelle2 (1306)
|
8/31/2007 12:07:17 PM
|
|
In article <7a4pig6sfb.fsf@homelinux.net>, Richard <rgrdev@gmail.com> wrote:
>rlb@hoekstra-uitgeverij.nl (Richard Bos) writes:
>
>> Richard <rgrdev@gmail.com> wrote:
>>
>>> rlb@hoekstra-uitgeverij.nl (Richard Bos) writes:
>>>
>>> > Ben Bacarisse <ben.usenet@bsb.me.uk> wrote:
>>> >
>>> >> gazelle@xmission.xmission.com (Kenny McCormack) writes:
>>> >>
>>> >> > both of you just post carp
>>> >>
>>> >> Fishing for compliments?
>>> >
>>> > No, Kenny's just trolling again.
>>>
>>> I thing someone missed the joke.
>>
>> Yes, you. Look up the (supposed) etymology of "trolling" in the Jargon
>> File.
>>
>> Richard
>
>But that's not funny.
Indeed. Plus, it sounds very much like an ex post facto construction.
|
|
0
|
|
|
|
Reply
|
gazelle2 (1306)
|
8/31/2007 12:08:34 PM
|
|
Keith Thompson:
> "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.
Agreed, it's just a waste of letters.
> It does prevent the function from (directly)
> modifying its own parameter (a local object), but that's of no concern
> to the caller.
If I don't plan on changing a variable's value, then I make it const,
including in the parameter list of a function.
> 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 haven't written much C in a while, but I think I used to do that and
have no problem.
Martin
|
|
0
|
|
|
|
Reply
|
warint (199)
|
8/31/2007 12:28:46 PM
|
|
Ian Collins:
> If you use casts frequently in C, you are doing something wrong.
Depends entirely on the nature of the code. I've written portable code
before that is littered with casts for very good reasons.
> If you use naked casts at all in C++, you are doing something very wrong.
No, this is a phobia. If a C++ programmer had any sense, they'd
realise that the following two expressions are identical in every way:
MyType(x)
(MyType)x
Try it if you don't believe me.
I only use the more flowerly casts when I'm actually dealing with user-
defined class types and so forth.
There's nothing at all wrong with writing the following in C++:
int x;
char *p = (char*)&x;
Going to the effort of writing "static_cast" just exposes a phobia.
Anyway, back to c.
> 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.
In the little snippet I wrote just above, I'd only write a comment
with it if my target audience only started programming yesterday at 3
O'Clock.
> I can't fan a compiler that issues a warning without the cast, just out
> of interest, which one does?
IMO, any decent compiler should issue truncation warnings.
Martin
|
|
0
|
|
|
|
Reply
|
warint (199)
|
8/31/2007 12:35:31 PM
|
|
jacob navia:
> int Strlen_i(char *s)
> {
> char *start=s;
> while (*s)
> s++;
> return s-start;}
If you want a ounce of efficiency then try:
int Strlen_i(char const *const p)
{
return (int)strlen(p);
}
That is to say, the platform's bulit-in strlen function is extremely
likely to be more efficient than anything you write.
Martin
|
|
0
|
|
|
|
Reply
|
warint (199)
|
8/31/2007 12:39:29 PM
|
|
Martin Wells wrote:
> Ian Collins:
>
>> If you use casts frequently in C, you are doing something wrong.
>
> Depends entirely on the nature of the code. I've written portable
> code before that is littered with casts for very good reasons.
>
>> If you use naked casts at all in C++, you are doing something
>> very wrong.
>
> No, this is a phobia. If a C++ programmer had any sense, they'd
> realise that the following two expressions are identical in
> every way:
>
> MyType(x)
>
> (MyType)x
>
> Try it if you don't believe me.
Please don't confuse this newsgroup with C++. There is a separate
newsgroup where that (different) language is on topic.
--
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
|
|
0
|
|
|
|
Reply
|
cbfalconer (19183)
|
8/31/2007 2:13:00 PM
|
|
jacob navia wrote:
>
.... snip ...
>
> Just
>
> int Strlen_i(char *s)
> {
> char *start=s;
> while (*s)
> s++;
> return s-start;
> }
> #define strlen Strlen_i;
At which point your code has undefined behaviour. Please read the
standard some day.
--
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
|
|
0
|
|
|
|
Reply
|
cbfalconer (19183)
|
8/31/2007 2:17:07 PM
|
|
"Malcolm McLean" <regniztar@btinternet.com> writes:
> If you are indexing an arbitrary-length array, effectively now it is
> an error to use int. That's a big change from what most people would
> recognise as "C". It is also very undesireable that i, which holds the
> index, is described as a "size_t" when it certainly doesn't hold a
> size. N, the count, doesn't hold an amount of memory either, but is
> also a size_t.
An array of char can potentially have an index range of
0...SIZE_MAX. An array of any larger object type has a more
limited index range. Therefore, size_t is always a suitable type
for representing an array index.
--
char a[]="\n .CJacehknorstu";int putchar(int);int main(void){unsigned long b[]
={0x67dffdff,0x9aa9aa6a,0xa77ffda9,0x7da6aa6a,0xa67f6aaa,0xaa9aa9f6,0x11f6},*p
=b,i=24;for(;p+=!*p;*p/=4)switch(0[p]&3)case 0:{return 0;for(p--;i--;i--)case+
2:{i++;if(i)break;else default:continue;if(0)case 1:putchar(a[i&15]);break;}}}
|
|
0
|
|
|
|
Reply
|
blp (3953)
|
8/31/2007 3:05:02 PM
|
|
"Ben Pfaff" <blp@cs.stanford.edu> wrote in message
news:87zm07lp7l.fsf@blp.benpfaff.org...
> "Malcolm McLean" <regniztar@btinternet.com> writes:
>> If you are indexing an arbitrary-length array, effectively now it is
>> an error to use int. That's a big change from what most people would
>> recognise as "C". It is also very undesireable that i, which holds the
>> index, is described as a "size_t" when it certainly doesn't hold a
>> size. N, the count, doesn't hold an amount of memory either, but is
>> also a size_t.
>
> An array of char can potentially have an index range of
> 0...SIZE_MAX. An array of any larger object type has a more
> limited index range. Therefore, size_t is always a suitable type
> for representing an array index.
>
An arbitrary fucntion, let's call it mean(), ought to be able to take any
array.
so
double mean(double *x, size_t N)
is correct. int will work, but might be a nuisance to caller.
However if we are to have a really whizzy mean, we will sort the numbers
before adding them.
So let's call qsort
void qsort(void *x, size_t N, size_t sz, int (*comp)(const void * const void
*)).
Yes qsort() takes two size_t's as well. So we are OK. The system does work,
but only so long as we are absolutely consistent in using size_t everywhere.
My proposal is to 1) make size_t signed, 2) rename it int.
--
Free games and programming goodies.
http://www.personal.leeds.ac.uk/~bgy1mm
|
|
0
|
|
|
|
Reply
|
regniztar (3128)
|
8/31/2007 3:18:18 PM
|
|
Ben Pfaff <blp@cs.stanford.edu> wrote:
>> And yet, other programming languages get by -- somehow -- even though
>> they don't even have unsigned integer types.
>
> What programming languages are you thinking of here?
One example would be Java.
|
|
0
|
|
|
|
Reply
|
ejensen (115)
|
8/31/2007 3:26:07 PM
|
|
Ed Jensen <ejensen@visi.com> writes:
> Ben Pfaff <blp@cs.stanford.edu> wrote:
>>> And yet, other programming languages get by -- somehow -- even though
>>> they don't even have unsigned integer types.
>>
>> What programming languages are you thinking of here?
>
> One example would be Java.
Lisp. Or Lithp.
|
|
0
|
|
|
|
Reply
|
rgrdev (1814)
|
8/31/2007 3:39:59 PM
|
|
user923005 <dcorbit@connx.com> wrote:
> Can those same languages create objects with a size to large to be
> held in an integer?
Consider this Java code:
byte[] foo = new byte[N];
N must be type int. In Java, an int is a 32 bit signed value.
Therefore, you can't create a byte array with more than 2^31-1
elements.
Now consider this Java code:
short[] foo = new short[N];
Presumably, this could work on a 64 bit JVM, where N = 2^31-1.
The size of the resulting object, in bytes, is larger than the maximum
value a Java int can hold.
Full disclosure: I do not have access to a system capable of testing
this. These conclusions are based on my understanding of the Java
language.
> If 'yes', then those languages are defective. If 'no', then integer
> is the correct return.
A pointless observation. All programming languages are defective in
at least one way or another. ALL of them.
My point stands: Somehow, other programming languages get by just fine
returning an int when asked for the length of a string.
>> > An unsigned is a defective return from anything that describes the
>> > size of an object.
>>
>> And yet, other programming languages get by -- somehow -- even though
>> they don't even have unsigned integer types.
>
> I can create a language with a single type. Somehow, I think it will
> be less effective than C for programming tasks.
You may decide a programming language with only signed integer types
is less effective than C for programming tasks if you like; however,
it doesn't dimish the success or usefulness of those other languages.
Nor is that the only thing that should be considered when choosing a
programming language.
>> I recognize and understand why the range of C types are defined the
>> way they're defined, but that doesn't minimize the pain when trying to
>> write 100% portable code.
>
> The way to minimize the pain of writing 100% portable code is to write
> it correctly, according to the language standard. For instance, that
> would include using size_t for object sizes. Now, pre-ANSI C did not
> have size_t. So that code will require effort to repair.
Writing 100% portable C code is extremely non-trivial and when taken
to an extreme can interfere with the progress of a project.
I understand why size_t was invented, but I have some suspicions a
more pragmatic approach may have been superior, such as returning int
from strlen() instead of size_t.
|
|
0
|
|
|
|
Reply
|
ejensen (115)
|
8/31/2007 4:08:25 PM
|
|
>>>>> "BP" == Ben Pfaff <blp@cs.stanford.edu> writes:
BP> Martin Wells <warint@eircom.net> 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.
BP> Implicit function declarations are part of C89. A compiler
BP> that rejects programs that use this feature is not an
BP> implementation of C89.
Yes, but --
a conforming compiler may issue any diagnostics it wishes, which means
it may certainly say "WARNING: implicitly declared function" or
something to that effect; and
most compilers need to be instructed to compile in strict ANSI/ISO
mode anyway, and so making the default behavior for implicitly
declared functions an error and only accepting them in strict mode
would be nicely consonant with that.
Charlton
--
Charlton Wilbur
cwilbur@chromatico.net
|
|
0
|
|
|
|
Reply
|
cwilbur2 (385)
|
8/31/2007 4:28:03 PM
|
|
In article <64tzqfk90w.fsf@homelinux.net>, Richard <rgrdev@gmail.com> wrote:
>>>> And yet, other programming languages get by -- somehow -- even though
>>>> they don't even have unsigned integer types.
>>> What programming languages are you thinking of here?
>> One example would be Java.
>Lisp. Or Lithp.
Most modern Lisps have bignums, which removes the problem of choosing
a size.
-- Richard
--
"Consideration shall be given to the need for as many as 32 characters
in some alphabets" - X3.4, 1963.
|
|
0
|
|
|
|
Reply
|
richard91 (3683)
|
8/31/2007 4:47:31 PM
|
|
In article <87zm07lp7l.fsf@blp.benpfaff.org>,
Ben Pfaff <blp@cs.stanford.edu> wrote:
>An array of char can potentially have an index range of
>0...SIZE_MAX. An array of any larger object type has a more
>limited index range. Therefore, size_t is always a suitable type
>for representing an array index.
For a sufficiently restricted interpretation of array index. p[-3]
can be perfectly legal.
-- Richard
--
"Consideration shall be given to the need for as many as 32 characters
in some alphabets" - X3.4, 1963.
|
|
0
|
|
|
|
Reply
|
richard91 (3683)
|
8/31/2007 4:50:26 PM
|
|
Malcolm McLean wrote, On 31/08/07 16:18:
>
> "Ben Pfaff" <blp@cs.stanford.edu> wrote in message
> news:87zm07lp7l.fsf@blp.benpfaff.org...
>> "Malcolm McLean" <regniztar@btinternet.com> writes:
>>> If you are indexing an arbitrary-length array, effectively now it is
>>> an error to use int. That's a big change from what most people would
>>> recognise as "C". It is also very undesireable that i, which holds the
>>> index, is described as a "size_t" when it certainly doesn't hold a
>>> size. N, the count, doesn't hold an amount of memory either, but is
>>> also a size_t.
>>
>> An array of char can potentially have an index range of
>> 0...SIZE_MAX. An array of any larger object type has a more
>> limited index range. Therefore, size_t is always a suitable type
>> for representing an array index.
>>
> An arbitrary fucntion, let's call it mean(), ought to be able to take
> any array.
>
> so
> double mean(double *x, size_t N)
>
> is correct. int will work, but might be a nuisance to caller.
Only if the caller does not write correct code.
> However if we are to have a really whizzy mean, we will sort the numbers
> before adding them.
>
> So let's call qsort
>
> void qsort(void *x, size_t N, size_t sz, int (*comp)(const void * const
> void *)).
>
> Yes qsort() takes two size_t's as well. So we are OK. The system does
> work, but only so long as we are absolutely consistent in using size_t
> everywhere.
Ah, he sees the light.
> My proposal is to 1) make size_t signed, 2) rename it int.
Or perhaps not. Almost 20 years after a language is standardised is a
bit late to start trying to change it. Especially when it has proved
extremely successful.
--
Flash Gordon
|
|
0
|
|
|
|
Reply
|
spam331 (4024)
|
8/31/2007 5:11:56 PM
|
|
jacob navia <jacob@jacob.remcomp.fr> writes:
> Keith Thompson wrote:
>> jacob navia <jacob@jacob.remcomp.fr> writes:
>>> spacecriter (Bill C) wrote:
>>>> 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?
>>>>
>>> That would be a good solution!
>>>
>>> THANKS!
>> Hmm, sounds familiar.
>> | I suppose you could write a strlen wrapper that calls the real
>> | strlen, checks whether the result exceeds INT_MAX (if you think
>> | that check is worth doing), and then returns the result as an
>> | int. That's assuming strlen calls are the only things triggering
>> | the warnings. And you'd still have to make hundreds of changes
>> | in the code.
>
> NO!
There's no need to shout.
> Just
>
> int Strlen_i(char *s)
> {
> char *start=s;
> while (*s)
> s++;
> return s-start;
> }
> #define strlen Strlen_i;
I think redefining strlen invokes undefined behavior; you're likely to
get away with it, but it might break when your code is compiled by
some other compiler. And if 'strlen' is already defined as a
function-like macro, redefining it as an object-like macro (without
first '#undef'ing it) is a constraint violation. (I'm assuming you
have a '#include <string.h>'.)
Why reimplement strlen rather than just calling it? It's a simple
enough function, but the implementation's strlen could well be faster
than your re-write. And by calling strlen and converting the result
to int, you make it easier to add a range check later.
>> <http://groups.google.com/group/comp.lang.c/msg/3ef33439c43be6ac>
--
Keith Thompson (The_Other_Keith) kst-u@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"
|
|
0
|
|
|
|
Reply
|
kst-u (21474)
|
8/31/2007 5:15:09 PM
|
|
Martin Wells wrote:
> jacob navia:
>
>> int Strlen_i(char *s)
>> {
>> char *start=s;
>> while (*s)
>> s++;
>> return s-start;}
>
>
> If you want a ounce of efficiency then try:
>
> int Strlen_i(char const *const p)
> {
> return (int)strlen(p);
> }
>
> That is to say, the platform's bulit-in strlen function is extremely
> likely to be more efficient than anything you write.
>
> Martin
>
I just did it so that I defined before the macro. But you are right.
Should do that.
|
|
0
|
|
|
|
Reply
|
jacob (2538)
|
8/31/2007 6:23:28 PM
|
|
"Flash Gordon" <spam@flash-gordon.me.uk> wrote in message
news:snulq4x9lc.ln2@news.flash-gordon.me.uk...
> Malcolm McLean wrote, On 31/08/07 16:18:
>> Yes qsort() takes two size_t's as well. So we are OK. The system does
>> work, but only so long as we are absolutely consistent in using size_t
>> everywhere.
>
> Ah, he sees the light.
>
That's why Basic Algorithms is absolutely consistent in using int. Otherwise
I would either have to translate everything to size_t, or you would rapidly
risk a mess.
>
> Or perhaps not. Almost 20 years after a language is standardised is a bit
> late to start trying to change it. Especially when it has proved extremely
> successful.
>
Effectively we are in a hiatus between standards. It looks like C99 will
never be widely implemented. So now is the time to get those nasty size_t's
out of our code.
--
Free games and programming goodies.
http://www.personal.leeds.ac.uk/~bgy1mm
|
|
0
|
|
|
|
Reply
|
regniztar (3128)
|
8/31/2007 6:27:00 PM
|
|
Martin Wells wrote:
> Ian Collins:
>
>> If you use casts frequently in C, you are doing something wrong.
>
>
> Depends entirely on the nature of the code. I've written portable code
> before that is littered with casts for very good reasons.
>
I'd wager it could be written without most, or even all of them.
>> 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.
>
> In the little snippet I wrote just above, I'd only write a comment
> with it if my target audience only started programming yesterday at 3
> O'Clock.
>
That's because it can be written without the cast.
>
>> I can't fan a compiler that issues a warning without the cast, just out
>> of interest, which one does?
>
> IMO, any decent compiler should issue truncation warnings.
>
Do you know of a "decent compiler" that does?
--
Ian Collins.
|
|
0
|
|
|
|
Reply
|
ian-news (9881)
|
8/31/2007 7:50:26 PM
|
|
Malcolm McLean wrote:
>
> Yes qsort() takes two size_t's as well. So we are OK. The system does
> work, but only so long as we are absolutely consistent in using size_t
> everywhere.
>
Isn't consistency one of the foundations of our art?
--
Ian Collins.
|
|
0
|
|
|
|
Reply
|
ian-news (9881)
|
8/31/2007 7:53:08 PM
|
|
jacob navia wrote:
>
> int Strlen_i(char *s)
> {
> char *start=s;
> while (*s)
> s++;
> return s-start;
> }
> #define strlen Strlen_i;
>
You really should bite the bullet and fix the code.
The transition form 32 to 64 bits isn't without pain, whether the return
is worth the pain is a choice of the developer.
There a some good papers on transitioning from 32 to 64 bit environments
to be found on the web. I'm sure the number (if not the quality) will
increase as the windows world catches up with the rest of us.
--
Ian Collins.
|
|
0
|
|
|
|
Reply
|
ian-news (9881)
|
8/31/2007 7:59:10 PM
|
|
Ian Collins wrote:
> jacob navia wrote:
>> int Strlen_i(char *s)
>> {
>> char *start=s;
>> while (*s)
>> s++;
>> return s-start;
>> }
>> #define strlen Strlen_i;
>>
> You really should bite the bullet and fix the code.
>
If aint'broken do not fix it
There is no simple solution. It means go over the
code and put casts everywhere, fix the new bugs
as you dscover them, etc.
Don't feel like it. There are more interesting things to do.
> The transition form 32 to 64 bits isn't without pain, whether the return
> is worth the pain is a choice of the developer.
>
Well, my compiler system is up and running in 64 bits...
I have to fix the debugger though, and many other stuff...
> There a some good papers on transitioning from 32 to 64 bit environments
> to be found on the web. I'm sure the number (if not the quality) will
> increase as the windows world catches up with the rest of us.
>
Yes, I know. I have read most of them.
|
|
0
|
|
|
|
Reply
|
jacob (2538)
|
8/31/2007 8:07:58 PM
|
|
"Ian Collins" <ian-news@hotmail.com> wrote in message
news:5jr9t9Fui2aU1@mid.individual.net...
> Malcolm McLean wrote:
>>
>> Yes qsort() takes two size_t's as well. So we are OK. The system does
>> work, but only so long as we are absolutely consistent in using size_t
>> everywhere.
>>
> Isn't consistency one of the foundations of our art?
>
Yes. But psychological factors are also important. If an index variable is
called "size" then of course the compiler will happily chug through and
index the array by variable "size". However to anyone reading the program it
is intensely irritating.
The same goes for variables which don't hold amounts of memory being called
by a name that suggests that this is their function.
If you allow a meaningful, but wrong type, called "int", and a correct but
misleadingly named type, called "size_t", how many programmers are going to
be consistent with their use of size_t. Especially in the case of a routine
like qsort() where it is not immediately apparent that the count, as opposed
to element size, has to be a size_t. However if a function called mean()
also takes a size_t, and calls qsort(), then this really is necessary.
Otherwise mean() has to include silly checks against INT_MAX, and then
document its oddball restrictions. That's what will happen in reality, with
user-supplied sort routines.
--
Free games and programming goodies.
http://www.personal.leeds.ac.uk/~bgy1mm
|
|
0
|
|
|
|
Reply
|
regniztar (3128)
|
8/31/2007 8:24:22 PM
|
|
"Malcolm McLean" <regniztar@btinternet.com> writes:
> "Ian Collins" <ian-news@hotmail.com> wrote in message
[...]
>> Isn't consistency one of the foundations of our art?
>>
> Yes. But psychological factors are also important. If an index
> variable is called "size" then of course the compiler will happily
> chug through and index the array by variable "size". However to anyone
> reading the program it is intensely irritating.
> The same goes for variables which don't hold amounts of memory being
> called by a name that suggests that this is their function.
[...]
Get over it. Learn what "size_t" means; there's more to it than how
it's spelled.
--
Keith Thompson (The_Other_Keith) kst-u@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"
|
|
0
|
|
|
|
Reply
|
kst-u (21474)
|
8/31/2007 9:14:25 PM
|
|
In article <46d87532$0$5072$ba4acef3@news.orange.fr>,
jacob navia <jacob@jacob.remcomp.fr> writes:
> Ian Collins wrote:
>> jacob navia wrote:
>>> int Strlen_i(char *s)
>>> {
>>> char *start=s;
>>> while (*s)
>>> s++;
>>> return s-start;
>>> }
>>> #define strlen Strlen_i;
>>>
>> You really should bite the bullet and fix the code.
>>
>
> If aint'broken do not fix it
>
But it *is* broken as far as the C standard is concerned.
> There is no simple solution. It means go over the
> code and put casts everywhere, fix the new bugs
> as you dscover them, etc.
>
> Don't feel like it. There are more interesting things to do.
>
If one believes in the engineering aspect of software development,
then maintenance is part of the deal. As pointed out elsewhere in
this thread, size_t has been around for 18 years so having to deal
with it should not exactly be a surprise.
That being said, you are free to either deal with updating your code
or to ignore the compiler warnings. It all depends on how much you
and those others who use the code care about it working correctly and
how difficult it is to port to other compilers, platforms, operating
systems, etc., when needed.
As an example of consequences of not keeping code up to date, I've
spent something in excess of a week getting a network communications
package for a little I/O box embeded in one of our systems to compile
and work correctly after an OS/compiler upgrade of the system needing
to use the I/O box. It turns out that the latest version of the
software package supplied by the vender is *full* of pre C89 crud.
I now have the system working again to the point that it is useful,
however the porting hassles serve as a disincentive for purchasing any
more of the company's products.
>> The transition form 32 to 64 bits isn't without pain, whether the return
>> is worth the pain is a choice of the developer.
>>
>
> Well, my compiler system is up and running in 64 bits...
> I have to fix the debugger though, and many other stuff...
>
>> There a some good papers on transitioning from 32 to 64 bit environments
>> to be found on the web. I'm sure the number (if not the quality) will
>> increase as the windows world catches up with the rest of us.
>>
>
> Yes, I know. I have read most of them.
>
--
________________________________________________________________________
Craig A. Gullixson
Instrument Engineer INTERNET: cgullixson@nso.edu
National Solar Observatory/Sac. Peak PHONE: (505) 434-7065
Sunspot, NM 88349 USA FAX: (505) 434-7029
|
|
0
|
|
|
|
Reply
|
craig8538 (9)
|
8/31/2007 9:55:17 PM
|
|
jacob navia wrote:
> Ian Collins wrote:
>> You really should bite the bullet and fix the code.
>>
> If aint'broken do not fix it
>
But is is. Quarts don't fit into pint pots.
> There is no simple solution. It means go over the
> code and put casts everywhere, fix the new bugs
> as you dscover them, etc.
>
Casts that hide turds are a good reason to have strict (process) rules
regarding their use. I've even worked at a shop where casts has to pass
a design review, which I thought was overkill at the time. I now know
better.
> Don't feel like it. There are more interesting things to do.
>
I don't feel like paying my bills, there are more interesting things to
do. Unfortunately they will get me in the end.
>> There a some good papers on transitioning from 32 to 64 bit environments
>> to be found on the web. I'm sure the number (if not the quality) will
>> increase as the windows world catches up with the rest of us.
>>
>
> Yes, I know. I have read most of them.
>
But did you learn from them?
--
Ian Collins.
|
|
0
|
|
|
|
Reply
|
ian-news (9881)
|
8/31/2007 10:28:53 PM
|
|
Ian Collins <ian-news@hotmail.com> writes:
> jacob navia wrote:
>> Ian Collins wrote:
>
>>> You really should bite the bullet and fix the code.
>>>
>> If aint'broken do not fix it
>>
> But is is. Quarts don't fit into pint pots.
The counterargument is that the contents of a quart pot can be poured
into a pint pot if the quart pot is less than half full. That appears
to be the case here (the code invokes strlen on strings that,
apparently, are known with some confidence to be shorter than INT_MAX
bytes).
Nevertheless, strlen() returns size_t for a good reason, and the
result should be stored in a size_t object unless there's a good
reason not to do so. (One possible reason is that fixing legacy code
would be more effort than it's worth.)
--
Keith Thompson (The_Other_Keith) kst-u@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"
|
|
0
|
|
|
|
Reply
|
kst-u (21474)
|
8/31/2007 10:37:28 PM
|
|
Keith Thompson wrote:
> Ian Collins <ian-news@hotmail.com> writes:
>> jacob navia wrote:
>>> Ian Collins wrote:
>>>> You really should bite the bullet and fix the code.
>>>>
>>> If aint'broken do not fix it
>>>
>> But is is. Quarts don't fit into pint pots.
>
> Nevertheless, strlen() returns size_t for a good reason, and the
> result should be stored in a size_t object unless there's a good
> reason not to do so. (One possible reason is that fixing legacy code
> would be more effort than it's worth.)
>
Unfortunately the fixes take on a whole new significance when porting
from 32 to 64 bit.
--
Ian Collins.
|
|
0
|
|
|
|
Reply
|
ian-news (9881)
|
8/31/2007 10:48:02 PM
|
|
Craig Gullixson wrote:
> In article <46d87532$0$5072$ba4acef3@news.orange.fr>,
> jacob navia <jacob@jacob.remcomp.fr> writes:
>> Ian Collins wrote:
>>> jacob navia wrote:
>>>> int Strlen_i(char *s)
>>>> {
>>>> char *start=s;
>>>> while (*s)
>>>> s++;
>>>> return s-start;
>>>> }
>>>> #define strlen Strlen_i;
>>>>
>>> You really should bite the bullet and fix the code.
>>>
>> If aint'broken do not fix it
>>
>
>
> But it *is* broken as far as the C standard is concerned.
>
Look, it is not the C standard that runs my code.
It is a mindless processor, churning instruction after instruction, no
mind no standards, no nothing.
I have an aesthetic view of code. What is important in it, from my
viewpoint, is clarity of design and above all, that
IT WORKS.
Code can be written up to the best standards, but if doesn't work or if
it doesn't perform very well I do not care. It is ugly.
The code I am porting is the code of the IDE of lcc-win, and the code of
the debugger. I started writing it around 1992.
The IDE was one of the few pieces of code I salvaged from my failed
lisp interpreter project, that was a technical success but a commercial
failure.
It has been ported to windows 16 bits (from 32 bit DOS emulator with
Delorie), then ported to windows 32 bits in 1996 (windows 95), then
ported to linux 32 bits , under GTK, and then to windows 64 bits.
Believe me, I know what porting means, what is important in code
what is not.
>
>> There is no simple solution. It means go over the
>> code and put casts everywhere, fix the new bugs
>> as you dscover them, etc.
>>
>> Don't feel like it. There are more interesting things to do.
>>
>
>
> If one believes in the engineering aspect of software development,
> then maintenance is part of the deal. As pointed out elsewhere in
> this thread, size_t has been around for 18 years so having to deal
> with it should not exactly be a surprise.
>
Yeah. I have to cope with the possibility of strings larger than 2GB.
Gosh!
> That being said, you are free to either deal with updating your code
> or to ignore the compiler warnings. It all depends on how much you
> and those others who use the code care about it working correctly and
> how difficult it is to port to other compilers, platforms, operating
> systems, etc., when needed.
>
I think that the fix proposed will fit the bill.
> As an example of consequences of not keeping code up to date, I've
> spent something in excess of a week getting a network communications
> package for a little I/O box embeded in one of our systems to compile
> and work correctly after an OS/compiler upgrade of the system needing
> to use the I/O box. It turns out that the latest version of the
> software package supplied by the vender is *full* of pre C89 crud.
You will agree with me that THAT is much serious than a few compiler
warnings because of size_t I suppose...
I adopted immediately C89 when it come out, because of the prototypes.
It was an INCREDIBLE relaxing thing that I did NOT have to worry
anymore if I always passed the right number of parameters to my
functions. The compiler would yell at me. What a fantastic feeling.
I still remember it!
> I now have the system working again to the point that it is useful,
> however the porting hassles serve as a disincentive for purchasing any
> more of the company's products.
>
Sorry but did you contact the vendor? If they still exists and
sell that package they have surely upgraded it...
|
|
0
|
|
|
|
Reply
|
jacob (2538)
|
8/31/2007 11:05:21 PM
|
|
Malcolm McLean wrote, On 31/08/07 19:27:
>
> "Flash Gordon" <spam@flash-gordon.me.uk> wrote in message
> news:snulq4x9lc.ln2@news.flash-gordon.me.uk...
>> Malcolm McLean wrote, On 31/08/07 16:18:
>>> Yes qsort() takes two size_t's as well. So we are OK. The system does
>>> work, but only so long as we are absolutely consistent in using
>>> size_t everywhere.
>>
>> Ah, he sees the light.
>>
> That's why Basic Algorithms is absolutely consistent in using int.
Therefore being inconsistent with the standard for the language your
claim to want to use.
> Otherwise I would either have to translate everything to size_t, or you
> would rapidly risk a mess.
Shock horror, if you do only part of your code correctly you get a mess!
The obvious solution is to write all of it correctly!
>> Or perhaps not. Almost 20 years after a language is standardised is a
>> bit late to start trying to change it. Especially when it has proved
>> extremely successful.
You have not addressed the points above. A reasonable assumption is that
this is because you realise you don't have a good argument against them.
> Effectively we are in a hiatus between standards. It looks like C99 will
> never be widely implemented. So now is the time to get those nasty
> size_t's out of our code.
Not everyone thinks they are nasty. In any case, comp.std.c is the place
to propose changes to the standard.
--
Flash Gordon
|
|
0
|
|
|
|
Reply
|
spam331 (4024)
|
8/31/2007 11:40:38 PM
|
|
"Malcolm McLean" <regniztar@btinternet.com> writes:
> "Flash Gordon" <spam@flash-gordon.me.uk> wrote in message
> news:snulq4x9lc.ln2@news.flash-gordon.me.uk...
>> Malcolm McLean wrote, On 31/08/07 16:18:
>>> Yes qsort() takes two size_t's as well. So we are OK. The system
>>> does work, but only so long as we are absolutely consistent in
>>> using size_t everywhere.
>>
>> Ah, he sees the light.
>>
> That's why Basic Algorithms is absolutely consistent in using
> int. Otherwise I would either have to translate everything to size_t,
> or you would rapidly risk a mess.
I can't understand why, since you acknowledge that part of the problem
is old code that uses int[1], you choose to perpetuate the problem in a
new book.
If you don't like the under score or the name for pedagogic reasons
just use a typedef in all the code (yes, someone else suggested this
already, my apologies for not looking up a giving credit -- it is
late). How about
typedef size_t cardinality;
? That suggests counting, indexing and size all in one.
[1] Elsewhere. It is not in the quoted text.
--
Ben.
|
|
0
|
|
|
|
Reply
|
ben.usenet (6515)
|
9/1/2007 12:45:15 AM
|
|
Ben Pfaff wrote:
> An array of char can potentially have an index range of
> 0...SIZE_MAX.
Almost.
For
char array[SIZE_MAX];
the lvalue of the last element is (array[SIZE_MAX - 1]).
--
pete
|
|
0
|
|
|
|
Reply
|
pfiland (6613)
|
9/1/2007 12:54:56 AM
|
|
Richard Tobin wrote:
>
> In article <87zm07lp7l.fsf@blp.benpfaff.org>,
> Ben Pfaff <blp@cs.stanford.edu> wrote:
>
> >An array of char can potentially have an index range of
> >0...SIZE_MAX. An array of any larger object type has a more
> >limited index range. Therefore, size_t is always a suitable type
> >for representing an array index.
>
> For a sufficiently restricted interpretation of array index. p[-3]
> can be perfectly legal.
If (&p) is the address of an object of an array type,
then p[-3] isn't defined.
--
pete
|
|
0
|
|
|
|
Reply
|
pfiland (6613)
|
9/1/2007 12:59:10 AM
|
|
jacob navia wrote:
> If aint'broken do not fix it
>
> There is no simple solution.
There can't be any solution of any kind, if it aint'broken.
--
pete
|
|
0
|
|
|
|
Reply
|
pfiland (6613)
|
9/1/2007 1:03:22 AM
|
|
Keith Thompson wrote:
> jacob navia <jacob@jacob.remcomp.fr> writes:
>> spacecriter (Bill C) wrote:
>>> 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?
>>>
>> That would be a good solution!
>>
>> THANKS!
>
> Hmm, sounds familiar.
>
>> I suppose you could write a strlen wrapper that calls the real
>> strlen, checks whether the result exceeds INT_MAX (if you think that
>> check is worth doing), and then returns the result as an int.
>> That's assuming strlen calls are the only things triggering the
>> warnings. And you'd still have to make hundreds of changes in the
>> code.
>
> <http://groups.google.com/group/comp.lang.c/msg/3ef33439c43be6ac>
Precicely what I had in mind with the suggestion. I guess I missed your
previous post.
Presumably, his code worked in 32-bit mode, so his new function should
emulate behavior of the 32-bit version of strlen. That *should* keep it
from beaking anything downstream. That should include casting the unsigned
result into an int.
--
Bill C.
|
|
0
|
|
|
|
Reply
|
spacecriter (8)
|
9/1/2007 1:27:29 AM
|
|
CBFalconer said:
> jacob navia wrote:
>>
> ... snip ...
>>
>> Just
>>
>> int Strlen_i(char *s)
>> {
>> char *start=s;
>> while (*s)
>> s++;
>> return s-start;
>> }
>> #define strlen Strlen_i;
>
> At which point your code has undefined behaviour.
No, at which point his code won't even compile.
> Please read the standard some day.
I think he should start with something a little easier to understand.
--
Richard Heathfield <http://www.cpax.org.uk>
Email: -www. +rjh@
Google users: <http://www.cpax.org.uk/prg/writings/googly.php>
"Usenet is a strange place" - dmr 29 July 1999
|
|
0
|
|
|
|
Reply
|
rjh (10789)
|
9/1/2007 1:59:53 AM
|
|
Joe Wright wrote:
> Richard Heathfield wrote:
>> CBFalconer said:
>>
>>> Richard Heathfield wrote:
>>>> CBFalconer said:
>>>>
>>> ... snip ...
>>>>> Is a British penny still roughly one nautical mile in diameter?
>>>> No, and it never has been.
>>> It was when I was last there mumble years ago.
>>
>> No, it wasn't.
>>
>>> Roughly 1 inch diameter,
>>
>> That's a good four orders of magnitude - almost five - away from being
>> a nautical mile.
>>
> A nautical mile is a minute of arc of the Earth's great circle. About
> 6,080 feet or 72,960 inches. That would be a 'Pretty' penny indeed.
>
It's a hyperbole, guys!!! A hyperbole!!! Look it up...
--
+----------------------------------------------------------------+
| Charles and Francis Richmond richmond at plano dot net |
+----------------------------------------------------------------+
|
|
0
|
|
|
|
Reply
|
frizzle (131)
|
9/1/2007 4:08:39 AM
|
|
pete wrote:
> Richard Tobin wrote:
>> Ben Pfaff <blp@cs.stanford.edu> wrote:
>>
>>> An array of char can potentially have an index range of
>>> 0...SIZE_MAX. An array of any larger object type has a more
>>> limited index range. Therefore, size_t is always a suitable
>>> type for representing an array index.
>>
>> For a sufficiently restricted interpretation of array index.
>> p[-3] can be perfectly legal.
>
> If (&p) is the address of an object of an array type,
> then p[-3] isn't defined.
Disproof:
int aone[10];
int *const atwo = &aone[3];
/* atwo is now effectively an array of indices -3 thru 6 */
...
int i;
for (i = -3; i < 7; i++) atwo[i] = i; /* legal */
--
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
|
|
0
|
|
|
|
Reply
|
cbfalconer (19183)
|
9/1/2007 6:03:12 AM
|
|
"Ben Bacarisse" <ben.usenet@bsb.me.uk> wrote in message
news:87642vfc2s.fsf@bsb.me.uk...
> "Malcolm McLean" <regniztar@btinternet.com> writes:
>
>> That's why Basic Algorithms is absolutely consistent in using
>> int. Otherwise I would either have to translate everything to size_t,
>> or you would rapidly risk a mess.
>
> I can't understand why, since you acknowledge that part of the problem
> is old code that uses int[1], you choose to perpetuate the problem in a
> new book.
>
Two things will happen.
Probably there will be a howl of protest as desktop programs move from 32 to
64 bits, and the implications of size_t being no longer the same size as an
int (give or take a sign bit) become obvious. So something will be done, and
people will look at code saying size_t i and say "Oh, that garbage the
committee inisted on back in 2007? What obsolete code."
The other possibility is that the committee will have its way, and we've all
got to write size_t for practically every array index. This makes C a
difficult language, OK for the specialist, but not very good for beginner
use. So it is no longer a good choice for a beginning book. Either use a
different language, or use a cut down, simplified version of the existing
language, with a note to say what you've done.
Either way, it is a bad idea to always follow the latest fashion in
programming. That way you've got to keep on rewriting things.
--
Free games and programming goodies.
http://www.personal.leeds.ac.uk/~bgy1mm
|
|
0
|
|
|
|
Reply
|
regniztar (3128)
|
9/1/2007 7:13:45 AM
|
|
Malcolm McLean said:
<snip>
> Probably there will be a howl of protest as desktop programs move from
> 32 to 64 bits,
Why? Surely everyone has learned their lesson from the early 1990s -
"don't rely on exact-size types, or your code will break one day" -
haven't they?
> and the implications of size_t being no longer the same
> size as an int (give or take a sign bit) become obvious.
It has never been the case that size_t is the same size as an int,
except by coincidence. ints are sizeof(int) bytes big, whereas size_ts
are sizeof(size_t) bytes big. If these values are the same, that's an
interesting coincidence, but nothing more.
> So something
> will be done, and people will look at code saying size_t i and say
> "Oh, that garbage the committee inisted on back in 2007? What obsolete
> code."
(a) far from being garbage, size_t is a useful type;
(b) the committee codified size_t is 1989, not 2007;
(c) far from being obsolete, code that uses proper types in the proper
way is more likely to survive and flourish than code that does not.
<snip>
> Either way, it is a bad idea to always follow the latest fashion in
> programming.
Such as, say, 64-bit ints.
> That way you've got to keep on rewriting things.
Precisely. Whereas, if you use the proper types in the right way, you
are less likely to have to do that.
--
Richard Heathfield <http://www.cpax.org.uk>
Email: -www. +rjh@
Google users: <http://www.cpax.org.uk/prg/writings/googly.php>
"Usenet is a strange place" - dmr 29 July 1999
|
|
0
|
|
|
|
Reply
|
rjh (10789)
|
9/1/2007 8:04:23 AM
|
|
CBFalconer <cbfalconer@yahoo.com> writes:
> pete wrote:
>> Richard Tobin wrote:
>>> Ben Pfaff <blp@cs.stanford.edu> wrote:
>>>
>>>> An array of char can potentially have an index range of
>>>> 0...SIZE_MAX. An array of any larger object type has a more
>>>> limited index range. Therefore, size_t is always a suitable
>>>> type for representing an array index.
>>>
>>> For a sufficiently restricted interpretation of array index.
>>> p[-3] can be perfectly legal.
>>
>> If (&p) is the address of an object of an array type,
>> then p[-3] isn't defined.
>
> Disproof:
>
> int aone[10];
> int *const atwo = &aone[3];
> /* atwo is now effectively an array of indices -3 thru 6 */
> ...
> int i;
> for (i = -3; i < 7; i++) atwo[i] = i; /* legal */
No, there's no such thing as an array with indices -3 through 6 -- and
atwo is a pointer, not an array. But a good case could be made that
atwo points to the first element of an array of length 7 (that happens
to overlap the last 7 elements of aone). I'm not sure just how good a
case can be made; it depends on the exact wording of the standard
(which I don't have handy at the moment).
--
Keith Thompson (The_Other_Keith) kst-u@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"
|
|
0
|
|
|
|
Reply
|
kst-u (21474)
|
9/1/2007 8:19:27 AM
|
|
Malcolm McLean wrote:
> "Ben Bacarisse" <ben.usenet@bsb.me.uk> wrote:
>>
>>
>> I can't understand why, since you acknowledge that part of the problem
>> is old code that uses int[1], you choose to perpetuate the problem in a
>> new book.
>>
> Two things will happen.
> Probably there will be a howl of protest as desktop programs move from
> 32 to 64 bits, and the implications of size_t being no longer the same
> size as an int (give or take a sign bit) become obvious. So something
> will be done, and people will look at code saying size_t i and say "Oh,
> that garbage the committee inisted on back in 2007? What obsolete code."
>
Those of us with decent desktops have been in the 64 bit world for well
over a decade and I haven't heard any howls yet.
> The other possibility is that the committee will have its way, and we've
> all got to write size_t for practically every array index.
They've had their way since 1989, where have you been? 64 bit desktops
started to appear shortly after.
> This makes C
> a difficult language, OK for the specialist, but not very good for
> beginner use. So it is no longer a good choice for a beginning book.
Are you really saying too hard for windows programmers?
>
> Either way, it is a bad idea to always follow the latest fashion in
> programming. That way you've got to keep on rewriting things.
>
You must be behind the times Malcolm, there have been plenty of fashions
that have been and gone in the past 18 years.
--
Ian Collins.
|
|
0
|
|
|
|
Reply
|
ian-news (9881)
|
9/1/2007 8:19:28 AM
|
|
CBFalconer wrote:
>
> pete wrote:
> > If (&p) is the address of an object of an array type,
> > then p[-3] isn't defined.
>
> Disproof:
>
> int aone[10];
> int *const atwo = &aone[3];
> /* atwo is now effectively an array of indices -3 thru 6 */
> ...
> int i;
> for (i = -3; i < 7; i++) atwo[i] = i; /* legal */
(&aone[3]) is the address of an object of type int.
Your disproof is irrelevant to my statement.
--
pete
|
|
0
|
|
|
|
Reply
|
pfiland (6613)
|
9/1/2007 8:32:18 AM
|
|
Malcolm McLean wrote:
>
.... snip ...
>
> The other possibility is that the committee will have its way, and
> we've all got to write size_t for practically every array index.
> This makes C a difficult language, OK for the specialist, but not
> very good for beginner use. So it is no longer a good choice for a
> beginning book. Either use a different language, or use a cut down,
> simplified version of the existing language, with a note to say
> what you've done.
You don't type an array index because it's indexing an array. You
type it according to the values it has to hold. Similarly for
anything else. If an index has to hold any value returned from
strlen (which is a size_t) then it must be a size_t. If it has to
hold "sizeof double" it can be a char, a short, an int, a long, or
a size_t, and unsigned versions of all. I don't think anyone will
take you to task for assuming "sizeof double" is no larger than
127.
If you had ever had the training of using Pascal correctly, you
would be aware of this. There you first type the variable that
indexes an array (lower and upper bounds). Then you build an array
indexed by that type. Now the error detection will catch you
anytime you exceed the preset bounds in the index, and use of the
index involves no checks.
--
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
|
|
0
|
|
|
|
Reply
|
cbfalconer (19183)
|
9/1/2007 9:14:01 AM
|
|
In article <lnd4x2kdbk.fsf@nuthaus.mib.org>,
Keith Thompson <kst-u@mib.org> wrote:
>>>> For a sufficiently restricted interpretation of array index.
>>>> p[-3] can be perfectly legal.
>No, there's no such thing as an array with indices -3 through 6 -- and
>atwo is a pointer, not an array.
That's why I said "for a sufficiently restricted interpretation of
array index". How the standard defines array is unimportant; the
point is that in indexing, both sizes (which "should" be unsigned
size_ts) and offsets (both negative and positive) are used and
combined and compared. So I find the fact that sizes are inherently
positive unconvincing as an argument for their being unsigned.
The *real* reason for their being unsigned is that the good sizes for
signed ints have in the past been inadequate for addressing all
objects. At the risk of sounding like Mr Gates, I suggest that 63
bits will be quite adequate for object sizes throughout the future
life of C.
-- Richard
--
"Consideration shall be given to the need for as many as 32 characters
in some alphabets" - X3.4, 1963.
|
|
0
|
|
|
|
Reply
|
richard91 (3683)
|
9/1/2007 10:42:06 AM
|
|
In article <46D92392.3E1D@mindspring.com>,
pete <pfiland@mindspring.com> wrote:
>> int aone[10];
>> int *const atwo = &aone[3];
>(&aone[3]) is the address of an object of type int.
I realise this is just pedantry, but who can complain?
Is the following legal:
typedef int array_type[7];
array_type *atwo = (array_type *)&aone[3];
and if so, what is the type of *atwo? And is not (*atwo)[-1] legal?
-- Richard
--
"Consideration shall be given to the need for as many as 32 characters
in some alphabets" - X3.4, 1963.
|
|
0
|
|
|
|
Reply
|
richard91 (3683)
|
9/1/2007 10:52:40 AM
|
|
Richard Tobin wrote:
> Keith Thompson <kst-u@mib.org> wrote:
>
>>> For a sufficiently restricted interpretation of array index.
>>> p[-3] can be perfectly legal.
>
>> No, there's no such thing as an array with indices -3 through 6
>> -- and atwo is a pointer, not an array.
>
> That's why I said "for a sufficiently restricted interpretation of
> array index". How the standard defines array is unimportant; the
> point is that in indexing, both sizes (which "should" be unsigned
> size_ts) and offsets (both negative and positive) are used and
> combined and compared. So I find the fact that sizes are inherently
> positive unconvincing as an argument for their being unsigned.
No, you miss the point. The index type has nothing to do with the
array, it only has to do with the span of that arrays index. Make
that type suit the required index.
You snipped my example (and the attributions - which is bad. Don't
do that for material you quote) which showed the construction.
Following that the use of atwo is an adequate substitute for aone,
except for sizeof, and can be passed to functions in the same
manner. However atwo requires a signed index, while aone required
an unsigned one. C doesn't have the strict 'subrange' kind of
typing available in other languages, so individual indexes have to
be checked.
--
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
|
|
0
|
|
|
|
Reply
|
cbfalconer (19183)
|
9/1/2007 12:17:57 PM
|
|
Richard Heathfield wrote:
> CBFalconer said:
>
>> jacob navia wrote:
>> ... snip ...
>>> Just
>>>
>>> int Strlen_i(char *s)
>>> {
>>> char *start=s;
>>> while (*s)
>>> s++;
>>> return s-start;
>>> }
>>> #define strlen Strlen_i;
>> At which point your code has undefined behaviour.
>
> No, at which point his code won't even compile.
>
>> Please read the standard some day.
>
> I think he should start with something a little easier to understand.
>
This compiles just fine for me.
#include <stdio.h>
size_t Strlen(char *s) {
char *p = s;
if (p) while (*p) p++;
return p - s;
}
#define strlen Strlen
int main(void) {
char line[80] = "Are you kidding me?";
printf("The length of string \"%s\" is %d bytes.\n",
line, (int)strlen(line));
return 0;
}
Is there anything wrong with it?
--
Joe Wright
"Everything should be made as simple as possible, but not simpler."
--- Albert Einstein ---
|
|
0
|
|
|
|
Reply
|
joewwright (1737)
|
9/1/2007 1:35:53 PM
|
|
Joe Wright wrote:
> This compiles just fine for me.
>
> #include <stdio.h>
>
> size_t Strlen(char *s) {
> char *p = s;
> if (p) while (*p) p++;
> return p - s;
> }
>
> #define strlen Strlen
>
> int main(void) {
> char line[80] = "Are you kidding me?";
> printf("The length of string \"%s\" is %d bytes.\n",
> line, (int)strlen(line));
> return 0;
> }
>
> Is there anything wrong with it?
No, ignoring style, there is nothing wrong with it, as long as <string.h> is
not included.
|
|
0
|
|
|
|
Reply
|
truedfx (1926)
|
9/1/2007 1:49:42 PM
|
|
<much snippage>
Joe Wright said:
> Richard Heathfield wrote:
>> CBFalconer said:
>>> jacob navia wrote:
>>>> #define strlen Strlen_i;
>>> At which point your code has undefined behaviour.
>>
>> No, at which point his code won't even compile.
>>
>>> Please read the standard some day.
>>
>> I think he should start with something a little easier to understand.
>>
> This compiles just fine for me.
Look at his code more closely. Much more closely. Vewy vewy cwosewy, in
fact. I have re-quoted the relevant line.
--
Richard Heathfield <http://www.cpax.org.uk>
Email: -www. +rjh@
Google users: <http://www.cpax.org.uk/prg/writings/googly.php>
"Usenet is a strange place" - dmr 29 July 1999
|
|
0
|
|
|
|
Reply
|
rjh (10789)
|
9/1/2007 2:18:25 PM
|
|
Richard Heathfield wrote:
> <much snippage>
>
> Joe Wright said:
>> Richard Heathfield wrote:
>>> CBFalconer said:
>>>> jacob navia wrote:
>>>>> #define strlen Strlen_i;
>>>> At which point your code has undefined behaviour.
>>> No, at which point his code won't even compile.
>>>
>>>> Please read the standard some day.
>>> I think he should start with something a little easier to understand.
>>>
>> This compiles just fine for me.
>
> Look at his code more closely. Much more closely. Vewy vewy cwosewy, in
> fact. I have re-quoted the relevant line.
>
I see it (;) now. The admonishment to compile even your snippets before
posting is valid.
--
Joe Wright
"Everything should be made as simple as possible, but not simpler."
--- Albert Einstein ---
|
|
0
|
|
|
|
Reply
|
joewwright (1737)
|
9/1/2007 2:34:25 PM
|
|
Richard Heathfield <rjh@see.sig.invalid> wrote:
> Why? Surely everyone has learned their lesson from the early 1990s -
> "don't rely on exact-size types, or your code will break one day" -
> haven't they?
Sometimes (most of the time?) C developers need to choose between:
1. Writing 100% portable code. This can be non-trivial and really
slow down your development. (However, I'm sure writing 100% portable
code doesn't slow down any of the geniuses HERE. I'm talking strictly
about MORTAL developers.)
2. Writing code that's portable to the platforms they're currently
targeting. And perhaps keeping in mind platforms they're likely to
need to support in the future.
It's easy to be smug and regurgitate the ivory tower attitude:
"Well, just write your C code so it's 100% portable in the first
place. Easy! Problem solved! Only dummies don't do that!"
The reality of the situation is that many developers who choose the
"100% portable path" may end up (1) being unemployed, because their
productivity is low compared to more pragmatic developers, or (2)
working 80+ hours per week in order to keep pace with those more
pragmatic developers.
Of course, what's really happened in the market is that more and more
projects have abandoned C (and C++) for evil, horrible, limited,
short-sighted languages that made pragmatic choices like: fixed size
primitive types.
I personally try to walk the fine line between "TOO pragmatic" and
"TOO ivory tower". I'm not quite ready to look down my nose and
admonish those developers that sometimes used "int" when they should
have used "size_t". (I do agree, however, that they should fix their
code the right way, if they decide to continue to use C.)
The problem, if you care to see it as such, is really that C is aging,
and some of the choices made decades ago made sense then, but perhaps
don't make so much sense now, for an ever increasing number of
applications.
Because C was one of the first languages I knew well, and I had done
it for such a long time, it'll always have a soft spot in my heart.
However, I can't help but yearn for something very much in the C
tradition but updated and refreshed. A "C2" language, perhaps, where
there's no need for an alphabet soup of types, and where a "size_t"
type becomes unnecessary.
> (a) far from being garbage, size_t is a useful type;
> (b) the committee codified size_t is 1989, not 2007;
> (c) far from being obsolete, code that uses proper types in the proper
> way is more likely to survive and flourish than code that does not.
In my opinion, (c) is only true in a limited sort of way. It's more
likely that developers will flee to languages that offer increased
productivity AND portability through fixed size types. Those
languages make (a) almost entirely, if not entirely, irrelevant.
>> That way you've got to keep on rewriting things.
>
> Precisely. Whereas, if you use the proper types in the right way, you
> are less likely to have to do that.
When programming in C, it is, quite simply, too much of a productivity
killer to always make sure you're using the proper types in the right
way 100% of the time. This comment shouldn't be mistaken as an excuse
for developers to use "int" when they should use "size_t", though.
It's just a comment on C in general.
|
|
0
|
|
|
|
Reply
|
ejensen (115)
|
9/1/2007 2:56:12 PM
|
|
Harald van Dijk wrote:
> Joe Wright wrote:
>> This compiles just fine for me.
>>
>> #include <stdio.h>
>>
>> size_t Strlen(char *s) {
>> char *p = s;
>> if (p) while (*p) p++;
>> return p - s;
>> }
>>
>> #define strlen Strlen
>>
>> int main(void) {
>> char line[80] = "Are you kidding me?";
>> printf("The length of string \"%s\" is %d bytes.\n",
>> line, (int)strlen(line));
>> return 0;
>> }
>>
>> Is there anything wrong with it?
>
> No, ignoring style, there is nothing wrong with it, as long as <string.h> is
> not included.
Style? Anyway, what changes if I include <string.h> after <stdio.h> and
before #define strlen Strlen ?
--
Joe Wright
"Everything should be made as simple as possible, but not simpler."
--- Albert Einstein ---
|
|
0
|
|
|
|
Reply
|
joewwright (1737)
|
9/1/2007 2:56:39 PM
|
|
Joe Wright wrote:
> Harald van Dijk wrote:
>> Joe Wright wrote:
>>> This compiles just fine for me.
>>>
>>> #include <stdio.h>
>>>
>>> size_t Strlen(char *s) {
>>> char *p = s;
>>> if (p) while (*p) p++;
>>> return p - s;
>>> }
>>>
>>> #define strlen Strlen
>>>
>>> int main(void) {
>>> char line[80] = "Are you kidding me?";
>>> printf("The length of string \"%s\" is %d bytes.\n",
>>> line, (int)strlen(line));
>>> return 0;
>>> }
>>>
>>> Is there anything wrong with it?
>>
>> No, ignoring style, there is nothing wrong with it, as long as <string.h>
>> is not included.
>
> Style?
Defining your own functions with the same name as standard library functions
or macros is not something I would ever consider good style. Not even the
times when it's allowed and actually useful.
> Anyway, what changes if I include <string.h> after <stdio.h> and
> before #define strlen Strlen ?
If <string.h> already defines strlen as a macro, you will get a complaint
from your compiler that you're redefining the macro. If you make sure to
use #undef first, the behaviour is undefined.
|
|
0
|
|
|
|
Reply
|
truedfx (1926)
|
9/1/2007 3:12:13 PM
|
|
Joe Wright wrote:
> Richard Heathfield wrote:
>> <much snippage>
>>
>> Joe Wright said:
>>> Richard Heathfield wrote:
>>>> CBFalconer said:
>>>>> jacob navia wrote:
>>>>>> #define strlen Strlen_i;
>>>>> At which point your code has undefined behaviour.
>>>> No, at which point his code won't even compile.
>>>>
>>>>> Please read the standard some day.
>>>> I think he should start with something a little easier to understand.
>>>>
>>> This compiles just fine for me.
>>
>> Look at his code more closely. Much more closely. Vewy vewy cwosewy,
>> in fact. I have re-quoted the relevant line.
>>
> I see it (;) now. The admonishment to compile even your snippets before
> posting is valid.
>
I do not think so.
Snippets are intended for people, not machines. Besides this, that guy
can only be satisfied with things like that:
missing semicolons, missing this or that.
|
|
0
|
|
|
|
Reply
|
jacob (2538)
|
9/1/2007 3:52:48 PM
|
|
Ed Jensen wrote:
> Richard Heathfield <rjh@see.sig.invalid> wrote:
>> Why? Surely everyone has learned their lesson from the early 1990s -
>> "don't rely on exact-size types, or your code will break one day" -
>> haven't they?
>
> Sometimes (most of the time?) C developers need to choose between:
>
> 1. Writing 100% portable code. This can be non-trivial and really
> slow down your development. (However, I'm sure writing 100% portable
> code doesn't slow down any of the geniuses HERE. I'm talking strictly
> about MORTAL developers.)
>
> 2. Writing code that's portable to the platforms they're currently
> targeting. And perhaps keeping in mind platforms they're likely to
> need to support in the future.
>
> It's easy to be smug and regurgitate the ivory tower attitude:
>
> "Well, just write your C code so it's 100% portable in the first
> place. Easy! Problem solved! Only dummies don't do that!"
>
And then, like heathfield, they discover that they published a book
(c unleashed) with in one page the assumption that
sizeof(int) == sizeof(int *).
It is easy to play the guru here. More difficult in reality.
> The reality of the situation is that many developers who choose the
> "100% portable path" may end up (1) being unemployed, because their
> productivity is low compared to more pragmatic developers, or (2)
> working 80+ hours per week in order to keep pace with those more
> pragmatic developers.
>
who cares about the job?
c.lang.c is the only thing it counts
> Of course, what's really happened in the market is that more and more
> projects have abandoned C (and C++) for evil, horrible, limited,
> short-sighted languages that made pragmatic choices like: fixed size
> primitive types.
>
> I personally try to walk the fine line between "TOO pragmatic" and
> "TOO ivory tower". I'm not quite ready to look down my nose and
> admonish those developers that sometimes used "int" when they should
> have used "size_t". (I do agree, however, that they should fix their
> code the right way, if they decide to continue to use C.)
>
> The problem, if you care to see it as such, is really that C is aging,
> and some of the choices made decades ago made sense then, but perhaps
> don't make so much sense now, for an ever increasing number of
> applications.
>
> Because C was one of the first languages I knew well, and I had done
> it for such a long time, it'll always have a soft spot in my heart.
> However, I can't help but yearn for something very much in the C
> tradition but updated and refreshed. A "C2" language, perhaps, where
> there's no need for an alphabet soup of types, and where a "size_t"
> type becomes unnecessary.
>
>> (a) far from being garbage, size_t is a useful type;
>> (b) the committee codified size_t is 1989, not 2007;
>> (c) far from being obsolete, code that uses proper types in the proper
>> way is more likely to survive and flourish than code that does not.
>
> In my opinion, (c) is only true in a limited sort of way. It's more
> likely that developers will flee to languages that offer increased
> productivity AND portability through fixed size types. Those
> languages make (a) almost entirely, if not entirely, irrelevant.
>
>>> That way you've got to keep on rewriting things.
>> Precisely. Whereas, if you use the proper types in the right way, you
>> are less likely to have to do that.
>
> When programming in C, it is, quite simply, too much of a productivity
> killer to always make sure you're using the proper types in the right
> way 100% of the time. This comment shouldn't be mistaken as an excuse
> for developers to use "int" when they should use "size_t", though.
> It's just a comment on C in general.
more about that later
|
|
0
|
|
|
|
Reply
|
jacob (2538)
|
9/1/2007 3:56:04 PM
|
|
Ed Jensen wrote:
>
.... snip ...
>
> "Well, just write your C code so it's 100% portable in the first
> place. Easy! Problem solved! Only dummies don't do that!"
True.
>
> The reality of the situation is that many developers who choose the
> "100% portable path" may end up (1) being unemployed, because their
> productivity is low compared to more pragmatic developers, or (2)
> working 80+ hours per week in order to keep pace with those more
> pragmatic developers.
False. The portable writer reaches for the earlier developed
routines, all tested, and incorporates them. Then he goes
swimming, or something else enjoyable.
--
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
|
|
0
|
|
|
|
Reply
|
cbfalconer (19183)
|
9/1/2007 4:20:54 PM
|
|
Joe Wright wrote:
>
> Richard Heathfield wrote:
> > CBFalconer said:
> >
> >> jacob navia wrote:
> >> ... snip ...
> >>> Just
> >>>
> >>> int Strlen_i(char *s)
> >>> {
> >>> char *start=s;
> >>> while (*s)
> >>> s++;
> >>> return s-start;
> >>> }
> >>> #define strlen Strlen_i;
> >> At which point your code has undefined behaviour.
> >
> > No, at which point his code won't even compile.
> >
> >> Please read the standard some day.
> >
> > I think he should start with something a little easier to understand.
> >
> This compiles just fine for me.
>
> #include <stdio.h>
>
> size_t Strlen(char *s) {
> char *p = s;
> if (p) while (*p) p++;
> return p - s;
> }
AFAICS this has the same action as strlen.
>
> #define strlen Strlen
This leads to undefined behaviour.
> int main(void) {
> char line[80] = "Are you kidding me?";
> printf("The length of string \"%s\" is %d bytes.\n",
> line, (int)strlen(line));
> return 0;
> }
>
> Is there anything wrong with it?
Yes. See above.
--
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
|
|
0
|
|
|
|
Reply
|
cbfalconer (19183)
|
9/1/2007 4:28:53 PM
|
|
Malcolm McLean:
> Yes. But psychological factors are also important. If an index variable is
> called "size" then of course the compiler will happily chug through and
> index the array by variable "size". However to anyone reading the program it
> is intensely irritating.
typedef size_t index_t;
Martin
|
|
0
|
|
|
|
Reply
|
warint (199)
|
9/1/2007 5:07:38 PM
|
|
Ian Collins:
> > In the little snippet I wrote just above, I'd only write a comment
> > with it if my target audience only started programming yesterday at 3
> > O'Clock.
>
> That's because it can be written without the cast.
The cast is there to suppress a compiler warning. Anyway it seems we
disagree fundamentally on this so I don't think there's much point in
discussing it, other than a constant "I like cast" reply to "I don't
like cast".
>> IMO, any decent compiler should issue truncation warnings.
> Do you know of a "decent compiler" that does?
gcc.
Martin
|
|
0
|
|
|
|
Reply
|
warint (199)
|
9/1/2007 5:09:44 PM
|
|
jacob navia:
> Look, it is not the C standard that runs my code.
>
> It is a mindless processor, churning instruction after instruction, no
> mind no standards, no nothing.
>
> I have an aesthetic view of code. What is important in it, from my
> viewpoint, is clarity of design and above all, that
> IT WORKS.
There is a price to be paid for this: Lack of portability.
You are now paying that price, and the headache you now suffer is the
fruit of your own actions.
Portability seems to be a key issue on this newsgroup, which is why
you aren't getting the replies you desire.
Martin
|
|
0
|
|
|
|
Reply
|
warint (199)
|
9/1/2007 5:12:06 PM
|
|
Malcolm McLean
> Two things will happen.
> Probably there will be a howl of protest as desktop programs move from 32 to
> 64 bits, and the implications of size_t being no longer the same size as an
> int (give or take a sign bit) become obvious. So something will be done, and
> people will look at code saying size_t i and say "Oh, that garbage the
> committee inisted on back in 2007? What obsolete code."
>
> The other possibility is that the committee will have its way, and we've all
> got to write size_t for practically every array index. This makes C a
> difficult language, OK for the specialist, but not very good for beginner
> use. So it is no longer a good choice for a beginning book. Either use a
> different language, or use a cut down, simplified version of the existing
> language, with a note to say what you've done.
Am I the only one who doesn't acknowledge any problems when moving
from 32-Bit to 64-Bit? That is to say, am I the only one who's being
using size_t properly?
Someone please tell me why it's so difficult to use size_t in the
following fashion:
#include <stddef.h>
void AddFiveToEachElement(int *p,size_t len)
{
while (len--) *p++ += 5;
}
If you throw portability out the window, as jacob navia has done, then
you are ASKING FOR THESE PROBLEMS. You're lighting a fuse... it may be
a very long fuse, but it eventually will go off.
Martin
|
|
0
|
|
|
|
Reply
|
warint (199)
|
9/1/2007 5:23:59 PM
|
|
Ed Jensen:
> 1. Writing 100% portable code. This can be non-trivial and really
> slow down your development. (However, I'm sure writing 100% portable
> code doesn't slow down any of the geniuses HERE. I'm talking strictly
> about MORTAL developers.)
I don't consider myself to be an Einstein by any stretch of the
imagination, but still I've no problem keeping my code portable.
Likely reason being that I focused on that fashion of programming
rather than played around with int's all the time.
> "Well, just write your C code so it's 100% portable in the first
> place. Easy! Problem solved! Only dummies don't do that!"
Writing portable code is really a hell of a lot easier, and even a
hell of a lot more satisfying, than you make it sound.
Martin
|
|
0
|
|
|
|
Reply
|
warint (199)
|
9/1/2007 5:28:51 PM
|
|
CBFalconer:
> > size_t Strlen(char *s) {
> > char *p = s;
> > if (p) while (*p) p++;
> > return p - s;
> > }
>
> AFAICS this has the same action as strlen.
Just as an example, the strlen on Microsoft Windows compilers test
entire 4-byte chunks at a time looking for a byte which is all zeros.
It's a hell of a lot faster than using a canonical loop.
Martin
|
|
0
|
|
|
|
Reply
|
warint (199)
|
9/1/2007 6:00:20 PM
|
|
CBFalconer <cbfalconer@yahoo.com> wrote:
>> The reality of the situation is that many developers who choose the
>> "100% portable path" may end up (1) being unemployed, because their
>> productivity is low compared to more pragmatic developers, or (2)
>> working 80+ hours per week in order to keep pace with those more
>> pragmatic developers.
>
> False. The portable writer reaches for the earlier developed
> routines, all tested, and incorporates them. Then he goes
> swimming, or something else enjoyable.
And then we ride to work over rainbows on ponies!
|
|
0
|
|
|
|
Reply
|
ejensen (115)
|
9/1/2007 6:15:59 PM
|
|
Martin Wells wrote:
> CBFalconer:
>
>>> size_t Strlen(char *s) {
>>> char *p = s;
>>> if (p) while (*p) p++;
>>> return p - s;
>>> }
>>
>> AFAICS this has the same action as strlen.
>
> Just as an example, the strlen on Microsoft Windows compilers test
> entire 4-byte chunks at a time looking for a byte which is all
> zeros. It's a hell of a lot faster than using a canonical loop.
Well, I wasn't clear. I meant as a black box, not as to code.
--
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
|
|
0
|
|
|
|
Reply
|
cbfalconer (19183)
|
9/1/2007 6:17:46 PM
|
|
Martin Wells <warint@eircom.net> wrote:
>> 1. Writing 100% portable code. This can be non-trivial and really
>> slow down your development. (However, I'm sure writing 100% portable
>> code doesn't slow down any of the geniuses HERE. I'm talking strictly
>> about MORTAL developers.)
>
> I don't consider myself to be an Einstein by any stretch of the
> imagination, but still I've no problem keeping my code portable.
> Likely reason being that I focused on that fashion of programming
> rather than played around with int's all the time.
Choose all that apply:
1. You're mistaken.
2. You're a liar.
3. You don't get very much done.
>> "Well, just write your C code so it's 100% portable in the first
>> place. Easy! Problem solved! Only dummies don't do that!"
>
> Writing portable code is really a hell of a lot easier, and even a
> hell of a lot more satisfying, than you make it sound.
Writing extremely portable code IS easy, just not in C.
|
|
0
|
|
|
|
Reply
|
ejensen (115)
|
9/1/2007 6:21:57 PM
|
|
Ed Jensen
> > I don't consider myself to be an Einstein by any stretch of the
> > imagination, but still I've no problem keeping my code portable.
> > Likely reason being that I focused on that fashion of programming
> > rather than played around with int's all the time.
>
> Choose all that apply:
>
> 1. You're mistaken.
>
> 2. You're a liar.
>
> 3. You don't get very much done.
I'll have to go with number 1. Sorry I'll try again:
Writing portable code in C is VERY easy.
Yeah that sounds about right.
> > Writing portable code is really a hell of a lot easier, and even a
> > hell of a lot more satisfying, than you make it sound.
>
> Writing extremely portable code IS easy, just not in C.
Now you're just preaching about your own incompetence. Sorry to sound
hostile, but it's the truth.
Martin
|
|
0
|
|
|
|
Reply
|
warint (199)
|
9/1/2007 6:26:11 PM
|
|
jacob navia <jacob@jacob.remcomp.fr> writes:
> Ed Jensen wrote:
[...]
>> "Well, just write your C code so it's 100% portable in the first
>> place. Easy! Problem solved! Only dummies don't do that!"
>
> And then, like heathfield, they discover that they published a book
> (c unleashed) with in one page the assumption that
> sizeof(int) == sizeof(int *).
[...]
Yes, well, that's quite an effective refutation of Richard's claim
that he's infallible.
Except that he's never made such a claim.
He (or one of his co-authors) made a mistake. So what? That doesn't
affect his ability to offer good advice (which is checked for accuracy
by other readers here).
--
Keith Thompson (The_Other_Keith) kst-u@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"
|
|
0
|
|
|
|
Reply
|
kst-u (21474)
|
9/1/2007 6:35:09 PM
|
|
Ed Jensen wrote:
> CBFalconer <cbfalconer@yahoo.com> wrote:
>>> The reality of the situation is that many developers who choose the
>>> "100% portable path" may end up (1) being unemployed, because their
>>> productivity is low compared to more pragmatic developers, or (2)
>>> working 80+ hours per week in order to keep pace with those more
>>> pragmatic developers.
>> False. The portable writer reaches for the earlier developed
>> routines, all tested, and incorporates them. Then he goes
>> swimming, or something else enjoyable.
>
> And then we ride to work over rainbows on ponies!
Standard C doesn't have
1) Any serious i/o. To do anything fast you need system specific stuff.
2) Any notion of the keyboard. To handle the keyboard you need system
specific stuff.
3) Any graphics. Ditto.
4) No network.
5) Not any timers with reasonable accuracy.
C is very popular for systems programming but none of those programs
is written in standard C.
I am porting the lcc-win IDE and debugger. Written in C but system
specific. And I do not give a damm about portability of a windows
debugger to the latest toaster with embedded linux :-)
Windows debuggers aren't very portable outside windows as you may know.
It would be possible to at least do something reasonable portable if the
standard would specify a reasonable string library, a common container
library, a common base for using in day to day programming.
Nope there isn't anything like that in portable standard C.
All this people talking about "Portable standard C" are just talking
nonsense.
Or they do not use the network, nor do they do any graphics, nor do they
use any i/o, etc etc.
Yes, for toy applications it is barely portable, but even this program:
#include <stdio.h>
int main(void){printf("hello\n");}
is portable since the errors of printf are NOT specified, so you have no
way to know what happened if printf returns a negative result, besides
going into implementation specific stuff!
|
|
0
|
|
|
|
Reply
|
jacob (2538)
|
9/1/2007 6:51:34 PM
|
|
"jacob navia" <jacob@jacob.remcomp.fr> wrote in message
news:46d98bb2$0$25943$ba4acef3@news.orange.fr...
> Ed Jensen wrote:
> And then, like heathfield, they discover that they published a book
> (c unleashed) with in one page the assumption that
> sizeof(int) == sizeof(int *).
>
> It is easy to play the guru here. More difficult in reality.
>
It is also a lot easier to find errors in books than to write one. Having
been through the same process I won't criticise Heathfield too much. They
can creep in during formatting as well as in development and testing. My
book had some errors as well.
--
Free games and programming goodies.
http://www.personal.leeds.ac.uk/~bgy1mm
|
|
0
|
|
|
|
Reply
|
regniztar (3128)
|
9/1/2007 7:04:28 PM
|
|
"Ed Jensen" <ejensen@visi.com> wrote in message
news:13djb2v1hsou633@corp.supernews.com...
> CBFalconer <cbfalconer@yahoo.com> wrote:
>>> The reality of the situation is that many developers who choose the
>>> "100% portable path" may end up (1) being unemployed, because their
>>> productivity is low compared to more pragmatic developers, or (2)
>>> working 80+ hours per week in order to keep pace with those more
>>> pragmatic developers.
>>
>> False. The portable writer reaches for the earlier developed
>> routines, all tested, and incorporates them. Then he goes
>> swimming, or something else enjoyable.
>
> And then we ride to work over rainbows on ponies!
>
Don't. I was really looking forwards to working on Barbie and My Little
Pony. Then we lost the contract and the company went bankrupt.
--
Free games and programming goodies.
http://www.personal.leeds.ac.uk/~bgy1mm
|
|
0
|
|
|
|
Reply
|
regniztar (3128)
|
9/1/2007 7:06:58 PM
|
|
Keith Thompson said:
> jacob navia <jacob@jacob.remcomp.fr> writes:
>>
>> And then, like heathfield, they discover that they published a book
>> (c unleashed) with in one page the assumption that
>> sizeof(int) == sizeof(int *).
> [...]
>
> Yes, well, that's quite an effective refutation of Richard's claim
> that he's infallible.
>
> Except that he's never made such a claim.
Right (except in jest, of course). Nevertheless, don't assume that Mr
Navia's claim is correct without checking. It might be, of course, but
then again, it might not be.
> He (or one of his co-authors) made a mistake.
Quite a few, alas. I don't recall any instances of assuming sizeof(int)
to be equal to sizeof(int *), but it's certainly possible. In the
absence of a more specific reference, however, I will assume that his
bug report has as much substance behind it as everything else he posts.
If I'm wrong to assume this, doubtless I'll find out in due course.
--
Richard Heathfield <http://www.cpax.org.uk>
Email: -www. +rjh@
Google users: <http://www.cpax.org.uk/prg/writings/googly.php>
"Usenet is a strange place" - dmr 29 July 1999
|
|
0
|
|
|
|
Reply
|
rjh (10789)
|
9/1/2007 7:15:35 PM
|
|
"Martin Wells" <warint@eircom.net> wrote in message
news:1188671171.922636.119090@d55g2000hsg.googlegroups.com...
> Ed Jensen
>
>> Choose all that apply:
>>
>> 1. You're mistaken.
>>
>> 2. You're a liar.
>>
>> 3. You don't get very much done.
>
> Now you're just preaching about your own incompetence. Sorry to sound
> hostile, but it's the truth.
>
>
No, limited experience, Not the same thing as incompetence at all.
If you write say, mainly code to drive GUIs under Windows, you will find
that there's little point making much portable. Everything has to be ripped
up and rewritten whenever the denizens of Redmond decide to realease a new
compiler anyway.
However if you are writing mostly scientific programs, as I am doing at
present, everything has got to be portable. I've no business writing code
that can't be shifted to a mainframe or PC or whatever, as need arises. And
the graphical routines are in separate programs; the Beowulf cluster has a
simple teletype-style terminal as its communication with the outside world.
Even slash slash comments, which I thought were surely as good as standard
by now, are not accepted by the parallel compiler.
--
Free games and programming goodies.
http://www.personal.leeds.ac.uk/~bgy1mm
|
|
0
|
|
|
|
Reply
|
regniztar (3128)
|
9/1/2007 7:16:43 PM
|
|
"Martin Wells" <warint@eircom.net> wrote in message
news:1188667439.993226.123110@57g2000hsv.googlegroups.com...
> Malcolm McLean
> #include <stddef.h>
>
> void AddFiveToEachElement(int *p,size_t len)
> {
> while (len--) *p++ += 5;
> }
>
> If you throw portability out the window, as jacob navia has done, then
> you are ASKING FOR THESE PROBLEMS. You're lighting a fuse... it
> may be a very long fuse, but it eventually will go off.
>
What are those ints going to be used for? We don't know, but such a useful
function would surely find a place in calculating array indices, or
intermediate values, such as counts, to calculating array indices.
So we need another version
void AddFiveToEachElementsz(size_t *p, size_t len)
The fuse has gone off. That's what the admission of size_t does to your
code.
--
Free games and programming goodies.
http://www.personal.leeds.ac.uk/~bgy1mm
|
|
0
|
|
|
|
Reply
|
regniztar (3128)
|
9/1/2007 7:21:20 PM
|
|
"Martin Wells" <warint@eircom.net> wrote in message
news:1188669620.856942.29840@50g2000hsm.googlegroups.com...
> CBFalconer:
> Just as an example, the strlen on Microsoft Windows compilers test
> entire 4-byte chunks at a time looking for a byte which is all zeros.
> It's a hell of a lot faster than using a canonical loop.
>
No it's not. It's 4 times faster, which makes it O(N), which means it is
about as fast as the canonical loop.
Every man and his dog invents a new C strign library which performs the
length operation in O(constant) time.
--
Free games and programming goodies.
http://www.personal.leeds.ac.uk/~bgy1mm
|
|
0
|
|
|
|
Reply
|
regniztar (3128)
|
9/1/2007 7:25:49 PM
|
|
"Malcolm McLean" <regniztar@btinternet.com> writes:
> "Martin Wells" <warint@eircom.net> wrote in message
> news:1188667439.993226.123110@57g2000hsv.googlegroups.com...
>> #include <stddef.h>
>>
>> void AddFiveToEachElement(int *p,size_t len)
>> {
>> while (len--) *p++ += 5;
>> }
>>
>> If you throw portability out the window, as jacob navia has done, then
>> you are ASKING FOR THESE PROBLEMS. You're lighting a fuse... it
>> may be a very long fuse, but it eventually will go off.
>>
> What are those ints going to be used for? We don't know, but such a
> useful function would surely find a place in calculating array
> indices, or intermediate values, such as counts, to calculating array
> indices.
>
> So we need another version
>
> void AddFiveToEachElementsz(size_t *p, size_t len)
>
> The fuse has gone off. That's what the admission of size_t does to
> your code.
You need a version of the function for every single type that
might need to have 5 added to it. Adding size_t to the mix
doesn't change that very much.
--
int main(void){char p[]="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz.\
\n",*q="kl BIcNBFr.NKEzjwCIxNJC";int i=sizeof p/2;char *strchr();int putchar(\
);while(*q){i+=strchr(p,*q++)-p;if(i>=(int)sizeof p)i-=sizeof p-1;putchar(p[i]\
);}return 0;}
|
|
0
|
|
|
|
Reply
|
blp (3953)
|
9/1/2007 7:49:22 PM
|
|
On 2007-09-01 19:21, Malcolm McLean <regniztar@btinternet.com> wrote:
> "Martin Wells" <warint@eircom.net> wrote in message
> news:1188667439.993226.123110@57g2000hsv.googlegroups.com...
>> void AddFiveToEachElement(int *p,size_t len)
>> {
>> while (len--) *p++ += 5;
>> }
>>
> What are those ints going to be used for? We don't know, but such a useful
> function would surely find a place in calculating array indices, or
> intermediate values, such as counts, to calculating array indices.
No doubt it would also be very useful to calculating file offsets, which
are long
.... and trade flows which are doubles
.... and bank balances which are long long
> So we need another version
>
> void AddFiveToEachElementsz(size_t *p, size_t len)
so we need another version
void AddFiveToEachElementLong(long *p, size_t len)
and another one
void AddFiveToEachElementDouble(double *p, size_t len)
and another one
void AddFiveToEachElementLongLong(long long *p, size_t len)
> The fuse has gone off. That's what the admission of size_t does to your
> code.
and the admission of long, double, long long or any other type.
Let's face it, admitting types to C was a mistake.
We should go back to B.
hp
--
_ | Peter J. Holzer | I know I'd be respectful of a pirate
|_|_) | Sysadmin WSR | with an emu on his shoulder.
| | | hjp@hjp.at |
__/ | http://www.hjp.at/ | -- Sam in "Freefall"
|
|
0
|
|
|
|
Reply
|
hjp-usenet2 (463)
|
9/1/2007 7:56:21 PM
|
|
"Malcolm McLean" <regniztar@btinternet.com> writes:
> "Martin Wells" <warint@eircom.net> wrote in message
> news:1188669620.856942.29840@50g2000hsm.googlegroups.com...
>> CBFalconer:
>> Just as an example, the strlen on Microsoft Windows compilers test
>> entire 4-byte chunks at a time looking for a byte which is all zeros.
>> It's a hell of a lot faster than using a canonical loop.
>>
> No it's not. It's 4 times faster, which makes it O(N), which means it
> is about as fast as the canonical loop.
4 times faster *is* a hell of a lot faster. Asymptotic
performance is not what the world is all about. In the end it's
all about how fast you can finish a particular task. The
asymptotic complexity of me adding numbers by hand is the same as
if the computer does it, but I tend to let the computer do it.
It's faster.
--
"The expression isn't unclear *at all* and only an expert could actually
have doubts about it"
--Dan Pop
|
|
0
|
|
|
|
Reply
|
blp (3953)
|
9/1/2007 7:58:05 PM
|
|
On 2007-09-01 19:25, Malcolm McLean <regniztar@btinternet.com> wrote:
> "Martin Wells" <warint@eircom.net> wrote in message
> news:1188669620.856942.29840@50g2000hsm.googlegroups.com...
>> CBFalconer:
>> Just as an example, the strlen on Microsoft Windows compilers test
>> entire 4-byte chunks at a time looking for a byte which is all zeros.
>> It's a hell of a lot faster than using a canonical loop.
>>
> No it's not. It's 4 times faster,
Probably less.
> which makes it O(N), which means it is about as fast as the canonical
> loop.
By that kind of reasoning a snail is about as fast as a jet.
hp
--
_ | Peter J. Holzer | I know I'd be respectful of a pirate
|_|_) | Sysadmin WSR | with an emu on his shoulder.
| | | hjp@hjp.at |
__/ | http://www.hjp.at/ | -- Sam in "Freefall"
|
|
0
|
|
|
|
Reply
|
hjp-usenet2 (463)
|
9/1/2007 7:59:49 PM
|
|
Peter J. Holzer wrote:
> On 2007-09-01 19:25, Malcolm McLean <regniztar@btinternet.com> wrote:
>> "Martin Wells" <warint@eircom.net> wrote in message
>> news:1188669620.856942.29840@50g2000hsm.googlegroups.com...
>>> CBFalconer:
>>> Just as an example, the strlen on Microsoft Windows compilers test
>>> entire 4-byte chunks at a time looking for a byte which is all zeros.
>>> It's a hell of a lot faster than using a canonical loop.
>>>
>> No it's not. It's 4 times faster,
>
> Probably less.
>
>> which makes it O(N), which means it is about as fast as the canonical
>> loop.
>
> By that kind of reasoning a snail is about as fast as a jet.
>
> hp
>
>
Most of the strings in this application are less than 80 bytes long.
The difference is zero!
It is all swamped in the overhead of function call, and loop setup!
jacob
|
|
0
|
|
|
|
Reply
|
jacob (2538)
|
9/1/2007 8:11:31 PM
|
|
CBFalconer wrote:
> Joe Wright wrote:
>> Richard Heathfield wrote:
>>> CBFalconer said:
>>>
>>>> jacob navia wrote:
>>>> ... snip ...
>>>>> Just
>>>>>
>>>>> int Strlen_i(char *s)
>>>>> {
>>>>> char *start=s;
>>>>> while (*s)
>>>>> s++;
>>>>> return s-start;
>>>>> }
>>>>> #define strlen Strlen_i;
>>>> At which point your code has undefined behaviour.
>>> No, at which point his code won't even compile.
>>>
>>>> Please read the standard some day.
>>> I think he should start with something a little easier to understand.
>>>
>> This compiles just fine for me.
>>
>> #include <stdio.h>
>>
>> size_t Strlen(char *s) {
>> char *p = s;
>> if (p) while (*p) p++;
>> return p - s;
>> }
>
> AFAICS this has the same action as strlen.
>
>> #define strlen Strlen
>
> This leads to undefined behaviour.
>
>> int main(void) {
>> char line[80] = "Are you kidding me?";
>> printf("The length of string \"%s\" is %d bytes.\n",
>> line, (int)strlen(line));
>> return 0;
>> }
>>
>> Is there anything wrong with it?
>
> Yes. See above.
>
Not quite the same. See 'if (p)' checking for NULL.
Saying it doesn't make it so. The preprocessor does its thing early on
and by the time anything gets to the compiler, there is no reference to
strlen to be found, only to Strlen.
I suppose you don't like '#define strlen Strlen'. It has the effect of
removing a reference to a standard library function and replacing it
with the name of a local function before compilation. Harmless.
--
Joe Wright
"Everything should be made as simple as possible, but not simpler."
--- Albert Einstein ---
|
|
0
|
|
|
|
Reply
|
joewwright (1737)
|
9/1/2007 8:27:40 PM
|
|
"Peter J. Holzer" <hjp-usenet2@hjp.at> wrote in message
news:slrnfdjgv5.68a.hjp-usenet2@zeno.hjp.at...
>
> and the admission of long, double, long long or any other type.
>
> Let's face it, admitting types to C was a mistake.
> We should go back to B.
>
The campaign for 64 bit ints wants int to be 64 bits. Then basically it's
ints for everything - no need for unsigned, 63 bits hold a number large
enough to count most things. Other types will be kept for special purposes.
Audio samples will be 16 bits for the foreseeable future, and you might need
a 32 bit type for interfacing with legacy libraries, and 128 bit longs for
cryptography. But bascially everything non-special can be an int, and the
problems disappear.
You've still got the problem of real numbers of course. The existence of two
and now three formats creates inefficiencies enough. But at least we'll have
the integers sorted out.
--
Free games and programming goodies.
http://www.personal.leeds.ac.uk/~bgy1mm
|
|
0
|
|
|
|
Reply
|
regniztar (3128)
|
9/1/2007 8:28:59 PM
|
|
jacob navia <jacob@jacob.remcomp.fr> writes:
> Peter J. Holzer wrote:
>> On 2007-09-01 19:25, Malcolm McLean <regniztar@btinternet.com> wrote:
>>> "Martin Wells" <warint@eircom.net> wrote in message
>>> news:1188669620.856942.29840@50g2000hsm.googlegroups.com...
>>>> CBFalconer:
>>>> Just as an example, the strlen on Microsoft Windows compilers test
>>>> entire 4-byte chunks at a time looking for a byte which is all zeros.
>>>> It's a hell of a lot faster than using a canonical loop.
>>>>
>>> No it's not. It's 4 times faster,
>> Probably less.
>>
>>> which makes it O(N), which means it is about as fast as the canonical
>>> loop.
>> By that kind of reasoning a snail is about as fast as a jet.
>
> Most of the strings in this application are less than 80 bytes long.
>
> The difference is zero!
>
> It is all swamped in the overhead of function call, and loop setup!
Oh? Have you measured it?
Even if you have, your measurements apply only to your application.
strlen() is simple enough that re-inventing it isn't a huge deal; if
that's what you want to do, go ahead. But in general, predefined
functions are likely to be at least as fast as anything you can write
in portable C. (qsort() probaby imposes significant overhead because
it uses an indirect function call for each comparison, so a
custom-written sorting routine may be faster. But a custom-written
routine that does what qsort() does is unlikely to be faster than your
implementation's qsort().)
Even with small strings, a word-at-a-time version of strlen() might be
significantly faster if you invoke it enough times.
Note that I'm not advocating micro-optimization, i.e., obfuscating
your source code for the sake of some small performance increase. In
this case, the simplest code (calling the predefined strlen()) is both
simpler and likely faster than any replacement.
Of course, you could always re-write the application to use some other
representation for strings, so you don't have to call strlen() at all.
It might (or might not) give you a significant improvement in
performance and/or reliability if strlen() calls are a bottleneck, and
it's doable in purely standard C.
The performance difference between the predefined strlen() and your
re-implementation of it may not be significant, but you seem to be
offended by the idea of calling strlen(), and I have no idea why.
--
Keith Thompson (The_Other_Keith) kst-u@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"
|
|
0
|
|
|
|
Reply
|
kst-u (21474)
|
9/1/2007 8:42:10 PM
|
|
"Peter J. Holzer" <hjp-usenet2@hjp.at> wrote in message
news:slrnfdjh5l.68a.hjp-usenet2@zeno.hjp.at...
> On 2007-09-01 19:25, Malcolm McLean <regniztar@btinternet.com> wrote:
>
> By that kind of reasoning a snail is about as fast as a jet.
>
The snail, going West, is moving towards the Andromeda galaxy at 50.000001
km/s. The jet, going East, is moving towards Andromeda at about 49.660 km/s,
assuming it's a Concorde.
So to two decimal places, the snail is about as fast as the jet.
--
Free games and programming goodies.
http://www.personal.leeds.ac.uk/~bgy1mm
|
|
0
|
|
|
|
Reply
|
regniztar (3128)
|
9/1/2007 8:48:00 PM
|
|
Malcolm McLean said:
>
> "Peter J. Holzer" <hjp-usenet2@hjp.at> wrote in message
> news:slrnfdjh5l.68a.hjp-usenet2@zeno.hjp.at...
>> On 2007-09-01 19:25, Malcolm McLean <regniztar@btinternet.com> wrote:
>>
>> By that kind of reasoning a snail is about as fast as a jet.
>>
> The snail, going West, is moving towards the Andromeda galaxy at
> 50.000001 km/s. The jet, going East, is moving towards Andromeda at
> about 49.660 km/s, assuming it's a Concorde.
If it's a Concorde, it isn't going East, and it's travelling rather
slower than the snail.
--
Richard Heathfield <http://www.cpax.org.uk>
Email: -www. +rjh@
Google users: <http://www.cpax.org.uk/prg/writings/googly.php>
"Usenet is a strange place" - dmr 29 July 1999
|
|
0
|
|
|
|
Reply
|
rjh (10789)
|
9/1/2007 8:53:11 PM
|
|
On 2007-09-01 20:28, Malcolm McLean <regniztar@btinternet.com> wrote:
> "Peter J. Holzer" <hjp-usenet2@hjp.at> wrote in message
> news:slrnfdjgv5.68a.hjp-usenet2@zeno.hjp.at...
>> and the admission of long, double, long long or any other type.
>>
>> Let's face it, admitting types to C was a mistake.
>> We should go back to B.
>>
> The campaign for 64 bit ints wants int to be 64 bits.
I think somebody's irony detector needs adjusting.
> You've still got the problem of real numbers of course. The existence of two
> and now three formats creates inefficiencies enough. But at least we'll have
^^^
Now? "long double" exists at least since C89. I think some pre-ANSI
compilers I used had it, too. Oh, I forgot. You are the guy who knows
that C in hundred years will look like C 30 years ago, and everything
added in between is just a short-lived fashion which will eventually be
removed again.
hp
--
_ | Peter J. Holzer | I know I'd be respectful of a pirate
|_|_) | Sysadmin WSR | with an emu on his shoulder.
| | | hjp@hjp.at |
__/ | http://www.hjp.at/ | -- Sam in "Freefall"
|
|
0
|
|
|
|
Reply
|
hjp-usenet2 (463)
|
9/1/2007 9:01:46 PM
|
|
Martin Wells wrote:
>
>>> IMO, any decent compiler should issue truncation warnings.
>
>> Do you know of a "decent compiler" that does?
>
>
> gcc.
>
Nope, your example compiles cleanly without the cast with -Wall -ansi
-pedantic
--
Ian Collins.
|
|
0
|
|
|
|
Reply
|
ian-news (9881)
|
9/1/2007 9:08:22 PM
|
|
On the larger issue of "write portable code in the first place",
Martin Wells and Craig Gullixson are correct (in my opinion) and
I will not add more than that.
On the specifics of mixing signed and unsigned...
In article <1188513736.208929.230140@m37g2000prh.googlegroups.com>,
Bart <bc@freeuk.com> wrote, in part:
>Signed/unsigned numbers have different ranges. Why is it a big deal to
>compare these two types of values? Is it because one type can store a
>value that does not exist in the other? That's also a problem with
>short and long ints. Anyway the solution can be simple, such as
>converting the numbers into a type that accommodates both ranges.
Indeed.
I think the "big deal" is that people get confused about the
possible problems. It helps, I think, to take a step or two
back and think about the actual inputs.
Suppose that you have two variables denoted "x" and "y", which
have differing types, but which are otherwise comparable with
relational operators.
The possible range for x is X_MIN to X_MAX, and the possible
range for y is Y_MIN to Y_MAX.
If there is a common type Z, for which numbers in X_MIN to X_MAX
and Y_MIN to Y_MAX always fit within Z_MIN to Z_MAX, then the
C code:
(Z)x < (Z)y
suffices. For example, if x and y are "signed char" and "unsigned
char" respectively, and we can be reasonably sure that INT_MAX meets
or exceeds UCHAR_MAX, then a simple:
(int)x < (int)y
suffices. If x is near SCHAR_MIN, say -125, and y is a value such
as (say) 200, we just get -125 < 200, which is true.
If there is no such common type -- for instance, if the type for
x is "signed long long" and the type for y is "unsigned long long"
-- then we have a *slightly* thornier problem. In this particular
case, we must decide whether negative values of "x" are less than
all values of "y". If so:
x < 0 || (unsigned long long)x < y
will do the trick. Even if x is near LLONG_MIN, so that forcing
x to "unsigned long long" produces a number very near ULLONG_MAX,
the first test takes care of the problem.
--
In-Real-Life: Chris Torek, Wind River Systems
Salt Lake City, UT, USA (40�39.22'N, 111�50.29'W) +1 801 277 2603
email: forget about it http://web.torek.net/torek/index.html
Reading email is like searching for food in the garbage, thanks to spammers.
|
|
0
|
|
|
|
Reply
|
nospam252 (1722)
|
9/1/2007 9:15:50 PM
|
|
Malcolm McLean wrote, On 01/09/07 20:04:
>
> "jacob navia" <jacob@jacob.remcomp.fr> wrote in message
> news:46d98bb2$0$25943$ba4acef3@news.orange.fr...
>> Ed Jensen wrote:
>> And then, like heathfield, they discover that they published a book
>> (c unleashed) with in one page the assumption that
>> sizeof(int) == sizeof(int *).
>>
>> It is easy to play the guru here. More difficult in reality.
>>
> It is also a lot easier to find errors in books than to write one.
It is even harder to write a good book.
> Having been through the same process I won't criticise Heathfield too
> much. They can creep in during formatting as well as in development and
> testing. My book had some errors as well.
I just checked and your book STILL has errors since it has not been
updated. Please you the correct tense. Unless, of course, you are
deliberately trying to mislead.
--
Flash Gordon
|
|
0
|
|
|
|
Reply
|
spam331 (4024)
|
9/1/2007 10:16:38 PM
|
|
Flash Gordon <spam@flash-gordon.me.uk> writes:
> Malcolm McLean wrote, On 01/09/07 20:04:
>>
>> "jacob navia" <jacob@jacob.remcomp.fr> wrote in message
>> news:46d98bb2$0$25943$ba4acef3@news.orange.fr...
>>> Ed Jensen wrote:
>>> And then, like heathfield, they discover that they published a book
>>> (c unleashed) with in one page the assumption that
>>> sizeof(int) == sizeof(int *).
>>>
>>> It is easy to play the guru here. More difficult in reality.
>>>
>> It is also a lot easier to find errors in books than to write one.
>
> It is even harder to write a good book.
>
You really are quite a nasty person.
>> Having been through the same process I won't criticise Heathfield
>> too much. They can creep in during formatting as well as in
>> development and testing. My book had some errors as well.
>
> I just checked and your book STILL has errors since it has not been
> updated. Please you the correct tense. Unless, of course, you are
> deliberately trying to mislead.
I suspect he will do it in his good time.
|
|
0
|
|
|
|
Reply
|
rgrdev (1814)
|
9/1/2007 11:55:22 PM
|
|
Martin Wells <warint@eircom.net> wrote:
>> Writing extremely portable code IS easy, just not in C.
>
> Now you're just preaching about your own incompetence. Sorry to sound
> hostile, but it's the truth.
Don't worry about it, Martin. To be honest, I was expecting that kind
of response much sooner. It's just sort of the...personality...of
this newsgroup. Since I've been online since about 1979, I've had
ample time to marvel at this kind of fascinating emergent behavior in
online communities.
There are very few regulars here in comp.lang.c that'll admit that
writing 100% portable C code is non-trivial. People get awfully
religious about strange things, even computer programming languages.
Your religion of choice is C. Hey, that's cool.
Therefore, I knew before I walked down this path, that the response
would ultimately be, "The problem can't possibly be that it's
non-trivial to write 100% portable C code; the problem must be you."
I've seen the denizens of comp.lang.c use this response on several
people. Why should I be immune?
But, instead of pointless and unfounded insults, let's try a real
world test for a change. You paste one or two thousand lines of C
code you've written from your most recent project, and we'll see if
anyone on the newsgroup can identify any code that's not 100% portable
C code.
Since you've made the claim that writing 100% portable C code isn't
just easy, but VERY easy, I'm quite sure you're up to the challenge.
It's time to put your code where your mouth is.
And while we're on the topic, I'd like to present a little poll: Is
there anyone else here that agrees with Martin when he says that
writing 100% portable C code is VERY easy? Keep in mind the question
isn't whether or not it's possible or desirable, just whether or not
it's VERY easy.
|
|
0
|
|
|
|
Reply
|
ejensen (115)
|
9/2/2007 1:36:15 AM
|
|
>Martin Wells <warint@eircom.net> wrote:
>> Writing extremely portable code IS easy, just not in C.
In article <13dk4sffp75jad9@corp.supernews.com>
Ed Jensen <ejensen@visi.com> wrote [in part, and one insertion of
mine in brackets below]:
>There are very few regulars here in comp.lang.c that'll admit that
>writing 100% portable C code is non-trivial. ...
>
>Since you've made the claim that writing 100% portable C code isn't
>just easy, but [in a later post that is not quoted above] VERY easy ...
>
>... I'd like to present a little poll: Is
>there anyone else here that agrees with Martin when he says that
>writing 100% portable C code is VERY easy?
I would say "often easy enough, rarely VERY easy", although of
course the precise meaning of "enough" and "VERY" is tough to
pin down.
Furthermore, the easy-ness of portability varies with the goal of
the code. Clearly, something like "calculate mortgage payments"
or "concatenate files specified by argv[] elements" is going to be
easier than "write an operating system" or "do bitmapped graphics":
the latter two *require* at least *some* non-portable code.
The trick in this case is to know when to make the tradeoff -- but
this in turn requires being able to write portable code (or even
"extremely" or "100%" portable code, whatever that may mean :-) )
in the first place. That, of course, requires knowing what is
portable, i.e., at least some degree of study of Standard C. This
is where the comp.lang.c newsgroup comes in: here in comp.lang.c,
you can find out what is "portable", or how to take any given chunk
of code with "not very portable" parts and rewrite it to have large
"portable parts", and thus learn when to make tradeoffs.
--
In-Real-Life: Chris Torek, Wind River Systems
Salt Lake City, UT, USA (40�39.22'N, 111�50.29'W) +1 801 277 2603
email: forget about it http://web.torek.net/torek/index.html
Reading email is like searching for food in the garbage, thanks to spammers.
|
|
0
|
|
|
|
Reply
|
nospam252 (1722)
|
9/2/2007 1:48:51 AM
|
|
Richard Tobin wrote:
>
> In article <46D92392.3E1D@mindspring.com>,
> pete <pfiland@mindspring.com> wrote:
>
> >> int aone[10];
> >> int *const atwo = &aone[3];
>
> >(&aone[3]) is the address of an object of type int.
>
> I realise this is just pedantry, but who can complain?
>
> Is the following legal:
>
> typedef int array_type[7];
> array_type *atwo = (array_type *)&aone[3];
It depends on the alignment requirements of array_type.
N869
6.3.2.3 Pointers
[#7] A pointer to an object or incomplete type may be
converted to a pointer to a different object or incomplete
type. If the resulting pointer is not correctly aligned
for the pointed-to type, the behavior is undefined.
--
pete
|
|
0
|
|
|
|
Reply
|
pfiland (6613)
|
9/2/2007 2:18:02 AM
|
|
jacob navia wrote:
>
.... snip ...
>
> Standard C doesn't have
>
> 1) Any serious i/o. To do anything fast you need system specific
> stuff.
> 2) Any notion of the keyboard. To handle the keyboard you need
> system specific stuff.
> 3) Any graphics. Ditto.
> 4) No network.
> 5) Not any timers with reasonable accuracy.
>
> C is very popular for systems programming but none of those programs
> is written in standard C.
Utter rubbish. Most good systems programs are written in as
standard a form as is available of their language. Some may have a
system specific GUI add-on. Some (such as an IDE) may be a
combination of several standard programs with GUI interface. Some
(such as an editor) may require special keyboard input (system
specific).
.... snip ...
>
> All this people talking about "Portable standard C" are just talking
> nonsense. Or they do not use the network, nor do they do any
> graphics, nor do they use any i/o, etc etc.
>
> Yes, for toy applications it is barely portable, but even this program:
>
> #include <stdio.h>
> int main(void){printf("hello\n");}
>
> is portable since the errors of printf are NOT specified, so you
> have no way to know what happened if printf returns a negative
> result, besides going into implementation specific stuff!
Purely because the writer was too lazy to write the program
'correctly'. As shown it contains at least two serious errors -
failure to return status, and failure to test the result from
printf. From N869:
[#14] The fprintf function returns the number of characters
transmitted, or a negative value if an output or encoding
error occurred.
A correct version could be:
#include <stdio.h>
#include <stdlib.h>
int main(void) {
if (0 > printf("hello\n")) return EXIT_FAILURE;
return 0;
}
BTW, systems have various possibilities of returning details on
printf errors, such as ferror and perror. See the standard. There
is a value known as QOI attached to most implementations.
--
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
|
|
0
|
|
|
|
Reply
|
cbfalconer (19183)
|
9/2/2007 2:28:12 AM
|
|
Joe Wright wrote:
>
.... snip ...
>
> I suppose you don't like '#define strlen Strlen'. It has the effect
> of removing a reference to a standard library function and replacing
> it with the name of a local function before compilation. Harmless.
Possibly so on your present system. However, according to the C
standard, any such redefinition of standard library facilities
leads to undefined behaviour. Note that that behaviour may be
exactly what you want and expected. It doesn't have to be such.
--
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
|
|
0
|
|
|
|
Reply
|
cbfalconer (19183)
|
9/2/2007 2:45:52 AM
|
|
Ed Jensen wrote:
>
.... snip ...
>
> And while we're on the topic, I'd like to present a little poll:
> Is there anyone else here that agrees with Martin when he says
> that writing 100% portable C code is VERY easy? Keep in mind the
> question isn't whether or not it's possible or desirable, just
> whether or not it's VERY easy.
It all depends on the mindset. If you've been writing portable
code, you have the habit, and the unusual thing is non-portable
code. And the inverse also applies, and unfortunately is the more
common situation.
--
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
|
|
0
|
|
|
|
Reply
|
cbfalconer (19183)
|
9/2/2007 4:18:27 AM
|
|
Ed Jensen said:
> Martin Wells <warint@eircom.net> wrote:
>>> Writing extremely portable code IS easy, just not in C.
>>
>> Now you're just preaching about your own incompetence. Sorry to sound
>> hostile, but it's the truth.
>
> Don't worry about it, Martin. To be honest, I was expecting that kind
> of response much sooner. It's just sort of the...personality...of
> this newsgroup. Since I've been online since about 1979, I've had
> ample time to marvel at this kind of fascinating emergent behavior in
> online communities.
>
> There are very few regulars here in comp.lang.c that'll admit that
> writing 100% portable C code is non-trivial.
I'm one of them, however.
I think it's easy to write *very* portable code, but difficult to write
100% portable code. Consider, for example, this simple program:
#include <limits.h>
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
int main(int argc, char **argv)
{
int rc = EXIT_SUCCESS;
unsigned long fa[UCHAR_MAX + 1] = {0};
int ch = 0;
size_t i = 0;
FILE *fp = argc > 1 ? fopen(argv[1], "rb") : NULL;
if(fp != NULL)
{
while((ch = getc(fp)) != EOF)
{
++fa[ch];
}
fclose(fp);
if(ferror(fp))
{
fputs("Input error.\n", stderr);
rc = EXIT_FAILURE;
}
else
{
for(i = 0; i < sizeof fa / sizeof fa[0]; i++)
{
if(fa[i] > 0)
{
printf("%lu: %lu\n", (unsigned long)i, fa[i]);
}
}
}
}
else
{
fputs("Can't open input file.\n", stderr);
rc = EXIT_FAILURE;
}
return rc;
}
This will work (I have tested it, so I know that it will at least
compile!) on Linux. It will work on Windows. With appropriate JCL,
it'll work on a mainframe. It will work on an Atari ST or an Amiga.
It'll work on MS-DOS. I see no reason why it wouldn't work on a Cray.
It'll work on lots of platforms, in fact.
It'll even work on a Mac - or will it? If not, why not?
And on what other platforms will it not work? And for what reasons? The
code /looks/ portable - but there are more problems in the code than
are immediately obvious to the eye.
I can see - well, several, at any rate! :-)
<snip>
> And while we're on the topic, I'd like to present a little poll: Is
> there anyone else here that agrees with Martin when he says that
> writing 100% portable C code is VERY easy? Keep in mind the question
> isn't whether or not it's possible or desirable, just whether or not
> it's VERY easy.
It depends on the code. It's often possible but not always. It's always
desirable, but not necessarily the most significant requirement. *Some*
code is indeed very easy to write portably.
--
Richard Heathfield <http://www.cpax.org.uk>
Email: -www. +rjh@
Google users: <http://www.cpax.org.uk/prg/writings/googly.php>
"Usenet is a strange place" - dmr 29 July 1999
|
|
0
|
|
|
|
Reply
|
rjh (10789)
|
9/2/2007 6:51:06 AM
|
|
Richard Heathfield wrote:
> Ed Jensen said:
>> Martin Wells <warint@eircom.net> wrote:
>>>> Writing extremely portable code IS easy, just not in C.
>>>
>>> Now you're just preaching about your own incompetence. Sorry to sound
>>> hostile, but it's the truth.
>>
>> Don't worry about it, Martin. To be honest, I was expecting that kind
>> of response much sooner. It's just sort of the...personality...of
>> this newsgroup. Since I've been online since about 1979, I've had
>> ample time to marvel at this kind of fascinating emergent behavior in
>> online communities.
>>
>> There are very few regulars here in comp.lang.c that'll admit that
>> writing 100% portable C code is non-trivial.
>
> I'm one of them, however.
>
> I think it's easy to write *very* portable code, but difficult to write
> 100% portable code. Consider, for example, this simple program:
>
> #include <limits.h>
> #include <stdio.h>
> #include <stdlib.h>
> #include <ctype.h>
>
> int main(int argc, char **argv)
> {
> int rc = EXIT_SUCCESS;
> unsigned long fa[UCHAR_MAX + 1] = {0};
> int ch = 0;
> size_t i = 0;
> FILE *fp = argc > 1 ? fopen(argv[1], "rb") : NULL;
> if(fp != NULL)
> {
> while((ch = getc(fp)) != EOF)
> {
> ++fa[ch];
> }
> fclose(fp);
> if(ferror(fp))
> {
> fputs("Input error.\n", stderr);
> rc = EXIT_FAILURE;
> }
> else
> {
> for(i = 0; i < sizeof fa / sizeof fa[0]; i++)
> {
> if(fa[i] > 0)
> {
> printf("%lu: %lu\n", (unsigned long)i, fa[i]);
> }
> }
> }
> }
> else
> {
> fputs("Can't open input file.\n", stderr);
> rc = EXIT_FAILURE;
> }
> return rc;
> }
>
> This will work (I have tested it, so I know that it will at least
> compile!) on Linux. It will work on Windows. With appropriate JCL,
> it'll work on a mainframe. It will work on an Atari ST or an Amiga.
> It'll work on MS-DOS. I see no reason why it wouldn't work on a Cray.
> It'll work on lots of platforms, in fact.
>
> It'll even work on a Mac - or will it? If not, why not?
>
> And on what other platforms will it not work? And for what reasons? The
> code /looks/ portable - but there are more problems in the code than
> are immediately obvious to the eye.
>
> I can see - well, several, at any rate! :-)
I can see one very obvious one: you're using a file after closing it. That's
not the way you should be writing code even if it's not meant to be
portable.
I can see one more potential problem, but it doesn't explain why you think
it might not work on a Mac. Could you give a hint?
|
|
0
|
|
|
|
Reply
|
truedfx (1926)
|
9/2/2007 7:35:24 AM
|
|
Harald van D?k said:
> Richard Heathfield wrote:
<snip>
>> It'll even work on a Mac - or will it? If not, why not?
>>
>> And on what other platforms will it not work? And for what reasons?
>> The code /looks/ portable - but there are more problems in the code
>> than are immediately obvious to the eye.
>>
>> I can see - well, several, at any rate! :-)
>
> I can see one very obvious one: you're using a file after closing it.
> That's not the way you should be writing code even if it's not meant
> to be portable.
Oh, stupid stupid stupid (me, not you). You're right, of course. That
was unintentional, by the way!
> I can see one more potential problem, but it doesn't explain why you
> think it might not work on a Mac. Could you give a hint?
I've never owned a Mac, nor executed my own code on own, so I'm going on
rumour and supposition, but it is my understanding that, on at least
*some* Mac implementations, argc is always 0, so the program will run,
but with unsatisfactory results.
--
Richard Heathfield <http://www.cpax.org.uk>
Email: -www. +rjh@
Google users: <http://www.cpax.org.uk/prg/writings/googly.php>
"Usenet is a strange place" - dmr 29 July 1999
|
|
0
|
|
|
|
Reply
|
rjh (10789)
|
9/2/2007 7:48:35 AM
|
|
CBFalconer wrote:
> jacob navia wrote:
> ... snip ...
>> Standard C doesn't have
>>
>> 1) Any serious i/o. To do anything fast you need system specific
>> stuff.
>> 2) Any notion of the keyboard. To handle the keyboard you need
>> system specific stuff.
>> 3) Any graphics. Ditto.
>> 4) No network.
>> 5) Not any timers with reasonable accuracy.
>>
>> C is very popular for systems programming but none of those programs
>> is written in standard C.
>
> Utter rubbish. Most good systems programs are written in as
> standard a form as is available of their language. Some may have a
> system specific GUI add-on. Some (such as an IDE) may be a
> combination of several standard programs with GUI interface. Some
> (such as an editor) may require special keyboard input (system
> specific).
>
> ... snip ...
>> All this people talking about "Portable standard C" are just talking
>> nonsense. Or they do not use the network, nor do they do any
>> graphics, nor do they use any i/o, etc etc.
>>
>> Yes, for toy applications it is barely portable, but even this program:
>>
>> #include <stdio.h>
>> int main(void){printf("hello\n");}
>>
>> is portable since the errors of printf are NOT specified, so you
>> have no way to know what happened if printf returns a negative
>> result, besides going into implementation specific stuff!
>
> Purely because the writer was too lazy to write the program
> 'correctly'. As shown it contains at least two serious errors -
> failure to return status,
As specified in the C standard, main returns zero, and it is not
necessary to write a return statement.
Before you start talking nonsense read the standard.
and failure to test the result from
> printf. From N869:
>
> [#14] The fprintf function returns the number of characters
> transmitted, or a negative value if an output or encoding
> error occurred.
>
> A correct version could be:
>
> #include <stdio.h>
> #include <stdlib.h>
> int main(void) {
> if (0 > printf("hello\n")) return EXIT_FAILURE;
> return 0;
> }
>
Ifyou re read your code you will see that you missed the ELSE arm of the
IF statement. You see?
That was precisely my point. How do you know what happened?
What error? You have to be system specific!
jacob
|
|
0
|
|
|
|
Reply
|
jacob (2538)
|
9/2/2007 8:10:14 AM
|
|
"Harald van D?k" <truedfx@gmail.com> wrote in message
news:fbdp2s$j6a$1@news5.zwoll1.ov.home.nl...
> Richard Heathfield wrote:
>
> I can see one more potential problem, but it doesn't explain why you think
> it might not work on a Mac. Could you give a hint?
>
The Mac supports every character knwon to man.
So UCHAR_MAX is 0xFFFFFFFFFFFFFFFF
64 bits for everything. That's what I like to see. OK maybe the Mac can't
reach such heights just yet, but Steve Jobs has just emailed me with an
order for a "give me 64" T-shirt, so it will soon.
Perfectly permitted by the standard. And of course the compiler doesn't
check for stack overflow.
--
Free games and programming goodies.
http://www.personal.leeds.ac.uk/~bgy1mm
|
|
0
|
|
|
|
Reply
|
regniztar (3128)
|
9/2/2007 8:32:52 AM
|
|
Martin Wells wrote:
> CBFalconer:
>
>>> size_t Strlen(char *s) {
>>> char *p = s;
>>> if (p) while (*p) p++;
>>> return p - s;
>>> }
>> AFAICS this has the same action as strlen.
>
>
> Just as an example, the strlen on Microsoft Windows compilers test
> entire 4-byte chunks at a time looking for a byte which is all zeros.
> It's a hell of a lot faster than using a canonical loop.
>
> Martin
>
To do that, it has to find an address multiple of four.
Since strings aren't naturally aligned (they could start at
ANY address) it has to make a few comparisons before finding the
right starting address. This means more setup time.
For strings with length less than 80-100 this, together with the
function call, will kill any performance improvements.
When using the optimizer, lcc-win32 generates an inline loop
of 4-5 assembler instructions, comparing character by
character. For relatively short strings, this will beat
any strlen function since the overhead of the function call
is much greater...
|
|
0
|
|
|
|
Reply
|
jacob (2538)
|
9/2/2007 8:39:26 AM
|
|
Ed Jensen wrote
> There are very few regulars here in comp.lang.c that'll admit that
> writing 100% portable C code is non-trivial.
Then,Richard Heathfield answered:
> I'm one of them, however.
> I think it's easy to write *very* portable code, but difficult to write
> 100% portable code. Consider, for example, this simple program:
[code snipped]
Harald van Dijk answered:
>> I can see one very obvious bug: you're using a file after closing it.
>> That's not the way you should be writing code even if it's not meant
>> to be portable.
>
And heathfield had to acknowledge...
> Oh, stupid stupid stupid (me, not you). You're right, of course. That
> was unintentional, by the way!
>
Ahh the "regulars" here. Always the pompous claims but then, they
present a few lines of code with such an OBVIOUS bug!
jacob
|
|
0
|
|
|
|
Reply
|
jacob (2538)
|
9/2/2007 8:48:49 AM
|
|
jacob navia <jacob@jacob.remcomp.fr> writes:
> Martin Wells wrote:
>> CBFalconer:
>>>> size_t Strlen(char *s) {
>>>> char *p = s;
>>>> if (p) while (*p) p++;
>>>> return p - s;
>>>> }
>>> AFAICS this has the same action as strlen.
>> Just as an example, the strlen on Microsoft Windows compilers test
>> entire 4-byte chunks at a time looking for a byte which is all zeros.
>> It's a hell of a lot faster than using a canonical loop.
>
> To do that, it has to find an address multiple of four.
> Since strings aren't naturally aligned (they could start at
> ANY address) it has to make a few comparisons before finding the
> right starting address. This means more setup time.
>
> For strings with length less than 80-100 this, together with the
> function call, will kill any performance improvements.
>
> When using the optimizer, lcc-win32 generates an inline loop
> of 4-5 assembler instructions, comparing character by
> character. For relatively short strings, this will beat
> any strlen function since the overhead of the function call
> is much greater...
There's no reason it couldn't do exactly the same thing for an
explicit call to strlen().
--
Keith Thompson (The_Other_Keith) kst-u@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"
|
|
0
|
|
|
|
Reply
|
kst-u (21474)
|
9/2/2007 9:16:31 AM
|
|
Malcolm McLean wrote:
> "Harald van D?k" <truedfx@gmail.com> wrote in message
> news:fbdp2s$j6a$1@news5.zwoll1.ov.home.nl...
>> Richard Heathfield wrote:
>>
>> I can see one more potential problem, but it doesn't explain why you
>> think it might not work on a Mac. Could you give a hint?
>>
> The Mac supports every character knwon to man.
> So UCHAR_MAX is 0xFFFFFFFFFFFFFFFF
No, that's not the case on Macs, and while I realise there are some real
systems that have a 64-bit char, it is my understanding that they are
freestanding implementations which do not use the standard I/O functions.
(I would appreciate details on implementations with 64-bit char and
<stdio.h>, though.)
|
|
0
|
|
|
|
Reply
|
truedfx (1926)
|
9/2/2007 9:19:29 AM
|
|
jacob navia <jacob@jacob.remcomp.fr> writes:
> Ed Jensen wrote
>> There are very few regulars here in comp.lang.c that'll admit that
>> writing 100% portable C code is non-trivial.
>
> Then,Richard Heathfield answered:
>> I'm one of them, however.
>
>> I think it's easy to write *very* portable code, but difficult to write
>> 100% portable code. Consider, for example, this simple program:
>
> [code snipped]
>
> Harald van Dijk answered:
>>> I can see one very obvious bug: you're using a file after closing it.
>>> That's not the way you should be writing code even if it's not meant
>>> to be portable.
>
> And heathfield had to acknowledge...
>
>> Oh, stupid stupid stupid (me, not you). You're right, of
>> course. That was unintentional, by the way!
>
>
> Ahh the "regulars" here. Always the pompous claims but then, they
> present a few lines of code with such an OBVIOUS bug!
Everyone makes mistakes.
The "regulars", in my experience, are distiguished by their
willingness to acknowledge and correct their mistakes, and to thank
those who point them out.
Incidentally, you recently claimed that "C Unleashed" contains some
code that assumes sizeof(int) == sizeof(int*). Can you be more
specific? I'm sure the authors would like to know about it. I think
Richard Heathfield has you killfiled; if you'll post the specifics,
I'll re-post for his benefit.
--
Keith Thompson (The_Other_Keith) kst-u@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"
|
|
0
|
|
|
|
Reply
|
kst-u (21474)
|
9/2/2007 9:20:22 AM
|
|
Richard Heathfield wrote:
> Harald van D?k said:
>> I can see one more potential problem, but it doesn't explain why you
>> think it might not work on a Mac. Could you give a hint?
>
> I've never owned a Mac, nor executed my own code on own, so I'm going on
> rumour and supposition, but it is my understanding that, on at least
> *some* Mac implementations, argc is always 0, so the program will run,
> but with unsatisfactory results.
Oh, thanks for the explanation. That's not the case with OS X, though it may
well be true for some of the implementations for older systems.
|
|
0
|
|
|
|
Reply
|
truedfx (1926)
|
9/2/2007 9:21:56 AM
|
|
"jacob navia" <jacob@jacob.remcomp.fr> wrote in message
news:46da791f$0$25925$ba4acef3@news.orange.fr...
> Ed Jensen wrote
> Ahh the "regulars" here. Always the pompous claims but then, they
> present a few lines of code with such an OBVIOUS bug!
>
I didn't spot it.
Either I'm another stupid regular, or the bug isn't so obvious.
--
Free games and programming goodies.
http://www.personal.leeds.ac.uk/~bgy1mm
|
|
0
|
|
|
|
Reply
|
regniztar (3128)
|
9/2/2007 9:24:16 AM
|
|
Keith Thompson said:
> jacob navia <jacob@jacob.remcomp.fr> writes:
<snip>
>> Ahh the "regulars" here. Always the pompous claims but then, they
>> present a few lines of code with such an OBVIOUS bug!
>
> Everyone makes mistakes.
>
> The "regulars", in my experience, are distiguished by their
> willingness to acknowledge and correct their mistakes, and to thank
> those who point them out.
Indeed. Everyone makes mistakes. To err is human, and all that. People
are not criticised here for making mistakes, but they *are* (rightly)
criticised for refusing to acknowledge them or to learn from them.
<snip>
--
Richard Heathfield <http://www.cpax.org.uk>
Email: -www. +rjh@
Google users: <http://www.cpax.org.uk/prg/writings/googly.php>
"Usenet is a strange place" - dmr 29 July 1999
|
|
0
|
|
|
|
Reply
|
rjh (10789)
|
9/2/2007 12:04:08 PM
|
|
"Richard Heathfield" <rjh@see.sig.invalid> wrote in message
news:6eadnQpTEJCNO0fbnZ2dneKdnZydnZ2d@bt.com...
>
> Indeed. Everyone makes mistakes. To err is human, and all that. People
> are not criticised here for making mistakes, but they *are* (rightly)
> criticised for refusing to acknowledge them or to learn from them.
>
It would be nice if that were true.
--
Free games and programming goodies.
http://www.personal.leeds.ac.uk/~bgy1mm
|
|
0
|
|
|
|
Reply
|
regniztar (3128)
|
9/2/2007 12:37:16 PM
|
|
Malcolm McLean said:
>
> "Richard Heathfield" <rjh@see.sig.invalid> wrote in message
> news:6eadnQpTEJCNO0fbnZ2dneKdnZydnZ2d@bt.com...
>>
>> Indeed. Everyone makes mistakes. To err is human, and all that.
>> People are not criticised here for making mistakes, but they *are*
>> (rightly) criticised for refusing to acknowledge them or to learn
>> from them.
>>
> It would be nice if that were true.
I think it *is* true, by and large. Mistakes *are* pointed out, and
rightly so, but to point out a mistake is *not* the same as to
criticise the person who made it. I make my fair share of mistakes (or
perhaps more!), but when people in clc point this out, I don't feel
threatened or intimidated by the fact. On the contrary, I welcome
corrections for what they really are - opportunities to learn and to
improve my programming.
--
Richard Heathfield <http://www.cpax.org.uk>
Email: -www. +rjh@
Google users: <http://www.cpax.org.uk/prg/writings/googly.php>
"Usenet is a strange place" - dmr 29 July 1999
|
|
0
|
|
|
|
Reply
|
rjh (10789)
|
9/2/2007 12:54:23 PM
|
|
In article <46DA1D5A.5778@mindspring.com>,
pete <pfiland@mindspring.com> wrote:
>> Is the following legal:
>>
>> typedef int array_type[7];
>> array_type *atwo = (array_type *)&aone[3];
>It depends on the alignment requirements of array_type.
Are you suggesting an array type can have different alignment requirements
from those of its elements?
-- Richard
--
"Consideration shall be given to the need for as many as 32 characters
in some alphabets" - X3.4, 1963.
|
|
0
|
|
|
|
Reply
|
richard91 (3683)
|
9/2/2007 1:04:38 PM
|
|
Malcolm McLean wrote:
>
> "jacob navia" <jacob@jacob.remcomp.fr> wrote in message
> news:46da791f$0$25925$ba4acef3@news.orange.fr...
>> Ed Jensen wrote
>> Ahh the "regulars" here. Always the pompous claims but then, they
>> present a few lines of code with such an OBVIOUS bug!
>>
> I didn't spot it.
> Either I'm another stupid regular, or the bug isn't so obvious.
>
Having 'fclose(fp);' the value of fp becomes indeterminate. Subsequent
use of it is undefined.
--
Joe Wright
"Everything should be made as simple as possible, but not simpler."
--- Albert Einstein ---
|
|
0
|
|
|
|
Reply
|
joewwright (1737)
|
9/2/2007 1:26:09 PM
|
|
Richard Tobin wrote:
>
> In article <46DA1D5A.5778@mindspring.com>,
> pete <pfiland@mindspring.com> wrote:
>
> >> Is the following legal:
> >>
> >> typedef int array_type[7];
> >> array_type *atwo = (array_type *)&aone[3];
>
> >It depends on the alignment requirements of array_type.
>
> Are you suggesting an array type can have different alignment
> requirements from those of its elements?
Yes.
--
pete
|
|
0
|
|
|
|
Reply
|
pfiland (6613)
|
9/2/2007 1:29:10 PM
|
|
pete wrote:
>
> Richard Tobin wrote:
> >
> > In article <46DA1D5A.5778@mindspring.com>,
> > pete <pfiland@mindspring.com> wrote:
> >
> > >> Is the following legal:
> > >>
> > >> typedef int array_type[7];
> > >> array_type *atwo = (array_type *)&aone[3];
> >
> > >It depends on the alignment requirements of array_type.
> >
> > Are you suggesting an array type can have different alignment
> > requirements from those of its elements?
>
> Yes.
However I'll admit that I had not considered
that object types aren't intrinsic properties of objects,
when I stated
"If (&p) is the address of an object of an array type,
then p[-3] isn't defined."
and that my statement wasn't the example of
"a sufficiently restricted interpretation of array index"
that I had intended it to be.
--
pete
|
|
0
|
|
|
|
Reply
|
pfiland (6613)
|
9/2/2007 1:37:31 PM
|
|
jacob navia wrote:
> CBFalconer wrote:
>> jacob navia wrote:
>>
>> ... snip ...
>>
>>> Standard C doesn't have
>>>
>>> 1) Any serious i/o. To do anything fast you need system specific
>>> stuff.
>>> 2) Any notion of the keyboard. To handle the keyboard you need
>>> system specific stuff.
>>> 3) Any graphics. Ditto.
>>> 4) No network.
>>> 5) Not any timers with reasonable accuracy.
>>>
>>> C is very popular for systems programming but none of those
>>> programs is written in standard C.
>>
>> Utter rubbish. Most good systems programs are written in as
>> standard a form as is available of their language. Some may have
>> a system specific GUI add-on. Some (such as an IDE) may be a
>> combination of several standard programs with GUI interface.
>> Some (such as an editor) may require special keyboard input
>> (system specific).
>>
>> ... snip ...
>>>
>>> #include <stdio.h>
>>> int main(void){printf("hello\n");}
>>>
>>> is portable since the errors of printf are NOT specified, so you
>>> have no way to know what happened if printf returns a negative
>>> result, besides going into implementation specific stuff!
>>
>> Purely because the writer was too lazy to write the program
>> 'correctly'. As shown it contains at least two serious errors -
>> failure to return status,
>
> As specified in the C standard, main returns zero, and it is not
> necessary to write a return statement.
>
> Before you start talking nonsense read the standard.
That does not apply to C90. So, for portable use omitting the
return is still a failure, especially since that failure fails to
report any possible i/o errors.
>
>> and failure to test the result from printf. From N869:
>>
>> [#14] The fprintf function returns the number of characters
>> transmitted, or a negative value if an output or encoding
>> error occurred.
>>
>> A correct version could be:
>>
>> #include <stdio.h>
>> #include <stdlib.h>
>> int main(void) {
>> if (0 > printf("hello\n")) return EXIT_FAILURE;
>> return 0;
>> }
>
> If you re read your code you will see that you missed the ELSE
> arm of the IF statement. You see?
The only if statement with an else arm was in the above code
snippet, which I wrote as an example for you. And it didn't
contain an else, only implied by bypassing the first return
statement. Ignoring the facts while beating your chest does not
lead to good software. BTW, your code snippet is still fully
quoted above, which should enable you to check my statement. But I
advise calming down first.
Incidentally, in C the else and if keywords are written in lower
case. By convention upper case versions are macros. Failure to
use lower case appropriately can cause unexpected failures in
carelessly written software.
--
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
|
|
0
|
|
|
|
Reply
|
cbfalconer (19183)
|
9/2/2007 3:47:54 PM
|
|
Keith Thompson wrote:
> jacob navia <jacob@jacob.remcomp.fr> writes:
>
.... snip ...
>>
>> To do that, it has to find an address multiple of four.
>> Since strings aren't naturally aligned (they could start at
>> ANY address) it has to make a few comparisons before finding the
>> right starting address. This means more setup time.
>>
>> For strings with length less than 80-100 this, together with the
>> function call, will kill any performance improvements.
>>
>> When using the optimizer, lcc-win32 generates an inline loop
>> of 4-5 assembler instructions, comparing character by
>> character. For relatively short strings, this will beat
>> any strlen function since the overhead of the function call
>> is much greater...
>
> There's no reason it couldn't do exactly the same thing for an
> explicit call to strlen().
The call itself may be longer than the execution of the inline, for
suitably short strings. And lets face it, 99% of C strings are
short, meaning under 10 chars or so. This is highly system and CPU
specific, and thus really OT here.
Maybe somebody will build a modified strlen routine which keeps
length statistics and install it in his system library. After some
test period that can validate (or invalidate) my claim above.
--
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
|
|
0
|
|
|
|
Reply
|
cbfalconer (19183)
|
9/2/2007 4:06:37 PM
|
|
Malcolm McLean wrote:
>
> "Peter J. Holzer" <hjp-usenet2@hjp.at> wrote in message
> news:slrnfdjh5l.68a.hjp-usenet2@zeno.hjp.at...
>> On 2007-09-01 19:25, Malcolm McLean <regniztar@btinternet.com> wrote:
>>
>> By that kind of reasoning a snail is about as fast as a jet.
>>
> The snail, going West, is moving towards the Andromeda galaxy at
> 50.000001 km/s. The jet, going East, is moving towards Andromeda at
> about 49.660 km/s, assuming it's a Concorde.
That was a fast snail! :)
AFAIK, M31 is closing in on the Sun at 300 km/s, and on Milky Way at 100
km/s, so how did you arrive at ca. 50 km/s?
Rolling your own standard functions, is usually a bad idea, in
particularly when the replacement is *much* slower.
--
Tor <torust [at] online [dot] no>
|
|
0
|
|
|
|
Reply
|
tor_rustad (506)
|
9/2/2007 4:23:02 PM
|
|
On 2007-09-02 16:06, CBFalconer <cbfalconer@yahoo.com> wrote:
> Keith Thompson wrote:
>> jacob navia <jacob@jacob.remcomp.fr> writes:
>>> To do that, it has to find an address multiple of four.
Not necessarily. The library in question is for the Intel architecture,
which allows unaligned access. It is possible that an unaligned access
to a 4-byte word is still faster than 4 accesses to single bytes.
>>> For strings with length less than 80-100 this, together with the
>>> function call, will kill any performance improvements.
>>>
>>> When using the optimizer, lcc-win32 generates an inline loop
>>> of 4-5 assembler instructions, comparing character by
>>> character. For relatively short strings, this will beat
>>> any strlen function since the overhead of the function call
>>> is much greater...
>>
>> There's no reason it couldn't do exactly the same thing for an
>> explicit call to strlen().
>
> The call itself may be longer than the execution of the inline, for
> suitably short strings.
Which call? The C compiler could inline any call to strlen. It knows
what it does, after all. Inlining calls to my_strlen is much harder.
(In fact, gcc does not only inline calls to strlen, it replaces calls to
strlen on a string literal with a suitable integer constant).
hp
--
_ | Peter J. Holzer | I know I'd be respectful of a pirate
|_|_) | Sysadmin WSR | with an emu on his shoulder.
| | | hjp@hjp.at |
__/ | http://www.hjp.at/ | -- Sam in "Freefall"
|
|
0
|
|
|
|
Reply
|
hjp-usenet2 (463)
|
9/2/2007 5:03:18 PM
|
|
CBFalconer wrote:
[snip]
> I advise calming down first.
>
Excuse me Chuck.
jacob
|
|
0
|
|
|
|
Reply
|
jacob (2538)
|
9/2/2007 5:04:18 PM
|
|
"Tor Rustad" <tor_rustad@hotmail.com> wrote in message
news:bfudnfB78Jv3fkfb4p2dnAA@telenor.com...
> Malcolm McLean wrote:
>>
>> "Peter J. Holzer" <hjp-usenet2@hjp.at> wrote in message
>> news:slrnfdjh5l.68a.hjp-usenet2@zeno.hjp.at...
>>> On 2007-09-01 19:25, Malcolm McLean <regniztar@btinternet.com> wrote:
>>>
>>> By that kind of reasoning a snail is about as fast as a jet.
>>>
>> The snail, going West, is moving towards the Andromeda galaxy at
>> 50.000001 km/s. The jet, going East, is moving towards Andromeda at about
>> 49.660 km/s, assuming it's a Concorde.
>
> That was a fast snail! :)
>
> AFAIK, M31 is closing in on the Sun at 300 km/s, and on Milky Way at 100
> km/s, so how did you arrive at ca. 50 km/s?
>
That's a wiki fact.
It could easily be wrong. I know Andromeda is moving towards us much faster
than any aeroplance could possibly fly, but I didn't know the value off the
top of my head.
--
Free games and programming goodies.
http://www.personal.leeds.ac.uk/~bgy1mm
|
|
0
|
|
|
|
Reply
|
regniztar (3128)
|
9/2/2007 5:16:30 PM
|
|
[snips]
On Thu, 30 Aug 2007 10:03:50 +0100, Malcolm McLean wrote:
> In fact if you use size_t safely and consistently, virtually all ints need
> to be size_t's.
Complete, total and utter bollocks.
size_t is used primarily for sizes and indexes.
int is used primarily for general calculations.
I have reams of code using both and it is the _unusual_ case where the
twain meet at all.
Where do you get this nonsense?
|
|
0
|
|
|
|
Reply
|
kbjarnason (4583)
|
9/2/2007 5:17:11 PM
|
|
Peter J. Holzer wrote:
> On 2007-09-02 16:06, CBFalconer <cbfalconer@yahoo.com> wrote:
>> Keith Thompson wrote:
>>> jacob navia <jacob@jacob.remcomp.fr> writes:
>>>> To do that, it has to find an address multiple of four.
>
> Not necessarily. The library in question is for the Intel architecture,
> which allows unaligned access. It is possible that an unaligned access
> to a 4-byte word is still faster than 4 accesses to single bytes.
>
This will be slower if the address is unaligned.
[snip]
> (In fact, gcc does not only inline calls to strlen, it replaces calls to
> strlen on a string literal with a suitable integer constant).
>
I thought about it, but I haven't got the time to do it...
|
|
0
|
|
|
|
Reply
|
jacob (2538)
|
9/2/2007 5:24:21 PM
|
|
[snips]
On Fri, 31 Aug 2007 16:18:18 +0100, Malcolm McLean wrote:
> Yes qsort() takes two size_t's as well. So we are OK. The system does work,
> but only so long as we are absolutely consistent in using size_t everywhere.
>
> My proposal is to 1) make size_t signed, 2) rename it int.
And thereby break reams of code, and produce yet another situation where
the solution simply does not work.
Current:
void *buff = malloc( 40000U );
int size = 40000;
Oops. The malloc works, but the size is wrong. So your solution requires
either:
1) Forcing 16-bit implementations to limit allocations to 32767 or fewer
bytes
2) Forcing 16-bit implementations to emulate larger ints.
Hmm. Turns out the same problem occurs with 32-bit implementations, as
one can trivially allocate regions > 2GB, but a 32-bit int won't work. So
32-bit implementations (and 16-bit ones, too) will have to use 64-bit ints
for everything, making both 32-bit and 16-bit implementations hellishly
inefficient, or simply crippled in terms of memory allocation.
So your proposal is to cripple the language or force it to result in
massively inefficient operations, all because you don't like some feature
which has worked perfectly well for at least some 17 years.
Somehow I think we'll choose to err on the side of sanity on this one; not
a single thing you've offered has given a single real justification for
eradicating size_t, other than to suit your personal pet peeves - and that
might make you happy, but crippling the language to make you happy just
isn't a terribly compelling argument.
|
|
0
|
|
|
|
Reply
|
kbjarnason (4583)
|
9/2/2007 5:30:42 PM
|
|
On Fri, 31 Aug 2007 19:27:00 +0100, Malcolm McLean wrote:
> "Flash Gordon" <spam@flash-gordon.me.uk> wrote in message
> news:snulq4x9lc.ln2@news.flash-gordon.me.uk...
>> Malcolm McLean wrote, On 31/08/07 16:18:
>>> Yes qsort() takes two size_t's as well. So we are OK. The system does
>>> work, but only so long as we are absolutely consistent in using size_t
>>> everywhere.
>>
>> Ah, he sees the light.
>>
> That's why Basic Algorithms is absolutely consistent in using int.
And producing broken code in the process.
Why you refuse to deal with that side of the equation, I don't know. Yes,
fine, it makes you happy to use int, but it makes your code at best
undesirable and at worst unusable in real programs.
> Effectively we are in a hiatus between standards. It looks like C99 will
> never be widely implemented. So now is the time to get those nasty
> size_t's out of our code.
Now is the time to fix the standard - which means leaving size_t in, as it
actually solves a problem and has a justification for existing, whereas
none of your counter-proposals solve anything or make any sense.
|
|
0
|
|
|
|
Reply
|
kbjarnason (4583)
|
9/2/2007 5:32:47 PM
|
|
[snips]
On Sat, 01 Sep 2007 20:16:43 +0100, Malcolm McLean wrote:
> No, limited experience, Not the same thing as incompetence at all.
> If you write say, mainly code to drive GUIs under Windows, you will find
> that there's little point making much portable. Everything has to be ripped
> up and rewritten whenever the denizens of Redmond decide to realease a new
> compiler anyway.
He said incompetence, and you just demonstrated it.
If I were writing such apps, I'd write the body of the code to be as
conforming as possible, meaning it is effectively immune to switching to
a different OS, compiler, or version of a compiler.
Some stuff - GUI code, network code, etc - will possibly have to be
rewritten at each change, but if that's a significant portion of the code,
chances are you're doing something very badly wrong.
> However if you are writing mostly scientific programs, as I am doing at
> present, everything has got to be portable. I've no business writing
> code that can't be shifted to a mainframe or PC or whatever, as need
> arises.
Oh, you mean like how you use int instead of size_t, thus crippling your
code on 16-bit (and even 32-bit) implementations? That sort of
"portable"?
> Even slash slash comments, which I thought were surely as good as
> standard by now, are not accepted by the parallel compiler.
Why would you think they're standard? They're in C++ and C99, but most of
the C world uses C90, not C99 - and those are not part of C90, are they?
What, you think standards magically change to suit your whim?
|
|
0
|
|
|
|
Reply
|
kbjarnason (4583)
|
9/2/2007 5:49:00 PM
|
|
On Sun, 02 Sep 2007 12:54:23 +0000, Richard Heathfield wrote:
> Malcolm McLean said:
>
>>
>> "Richard Heathfield" <rjh@see.sig.invalid> wrote in message
>> news:6eadnQpTEJCNO0fbnZ2dneKdnZydnZ2d@bt.com...
>>>
>>> Indeed. Everyone makes mistakes. To err is human, and all that.
>>> People are not criticised here for making mistakes, but they *are*
>>> (rightly) criticised for refusing to acknowledge them or to learn
>>> from them.
>>>
>> It would be nice if that were true.
>
> I think it *is* true, by and large. Mistakes *are* pointed out, and
> rightly so, but to point out a mistake is *not* the same as to
> criticise the person who made it. I make my fair share of mistakes (or
> perhaps more!), but when people in clc point this out, I don't feel
> threatened or intimidated by the fact. On the contrary, I welcome
> corrections for what they really are - opportunities to learn and to
> improve my programming.
Yeah, you just tend to make your mistakes so esoteric only about three
people are qualified to find them, let alone figure out the right way. :)
|
|
0
|
|
|
|
Reply
|
kbjarnason (4583)
|
9/2/2007 5:50:15 PM
|
|
"Kelsey Bjarnason" <kbjarnason@gmail.com> wrote in message
news:cl9rq4-8cc.ln1@spanky.localhost.net...
> On Sat, 01 Sep 2007 20:16:43 +0100, Malcolm McLean wrote:
>
>> No, limited experience, Not the same thing as incompetence at all.
>
>> If you write say, mainly code to drive GUIs under Windows, you will find
>> >> that there's little point making much portable. Everything has to be
>> ripped
>> up and rewritten whenever the denizens of Redmond decide to realease a >>
>> new compiler anyway.
>
> He said incompetence, and you just demonstrated it.
>
> If I were writing such apps, I'd write the body of the code to be as
> conforming as possible, meaning it is effectively immune to switching to
> a different OS, compiler, or version of a compiler.
>
What you not uncommonly find is that the actual processing that the app
performs is trivial - maybe it adds a few columns of numbers together and
produces a report. However the GUI to allow the user to enter these numbers,
check them, specify which columns to add up, and format the report might be
very non-trivial. So in fact the portable bit of the code is a sum()
function and maybe a few histogram or pie chart generators, without the
graphical part.
--
Free games and programming goodies.
http://www.personal.leeds.ac.uk/~bgy1mm
|
|
0
|
|
|
|
Reply
|
regniztar (3128)
|
9/2/2007 6:00:43 PM
|
|
On Fri, 31 Aug 2007 21:24:22 +0100, Malcolm McLean wrote:
> "Ian Collins" <ian-news@hotmail.com> wrote in message
> news:5jr9t9Fui2aU1@mid.individual.net...
>> Malcolm McLean wrote:
>>>
>>> Yes qsort() takes two size_t's as well. So we are OK. The system does
>>> work, but only so long as we are absolutely consistent in using size_t
>>> everywhere.
>>>
>> Isn't consistency one of the foundations of our art?
>>
> Yes. But psychological factors are also important.
Indeed, they are. So if you could kindly cease your asinine rantings
against size_t and for 64-bit ints, the rest of us wouldn't have to deal
with it and be happier. Of course, this would also suggest you're going
to fix your currently hopelessly broken code in your book, but I suspect
we'll just have to live with that, reminding newbies of the dangers
inherent in it.
> If an index variable
> is called "size" then of course the compiler will happily chug through
> and index the array by variable "size". However to anyone reading the
> program it is intensely irritating.
So don't call it size. Call it index. Just make sure it's a size_t.
> If you allow a meaningful, but wrong type, called "int", and a correct
> but misleadingly named type, called "size_t", how many programmers are
> going to be consistent with their use of size_t.
Those with experience, skill, ability, or simply enough smarts or
curiosity to ask _why_ two different types exist, for starters. Oh, and
any smart enough to ask for more experienced programmers to look over
their code now and then and actually learn from the recommendations
provided.
|
|
0
|
|
|
|
Reply
|
kbjarnason (4583)
|
9/2/2007 6:07:34 PM
|
|
"Kelsey Bjarnason" <kbjarnason@gmail.com> wrote in message
news:2j8rq4-8cc.ln1@spanky.localhost.net...
> [snips]
>
> On Fri, 31 Aug 2007 16:18:18 +0100, Malcolm McLean wrote:
>
>> Yes qsort() takes two size_t's as well. So we are OK. The system does
>> work,
>> but only so long as we are absolutely consistent in using size_t
>> everywhere.
>>
>> My proposal is to 1) make size_t signed, 2) rename it int.
>
> And thereby break reams of code, and produce yet another situation where
> the solution simply does not work.
>
> Current:
>
> void *buff = malloc( 40000U );
> int size = 40000;
>
> Oops. The malloc works, but the size is wrong. So your solution requires
> either:
>
> 1) Forcing 16-bit implementations to limit allocations to 32767 or fewer
> bytes
>
Or forcing someone in the unusual situation of allocating more than half of
the address space in one go into using an unusual type.
Engineering doesn't usually offer perfect solutions. If you want to
simulataneously have signed arithemetic, an efficient integer
representation, and use all bits of the integer, something has got to give.
The ability to manipulate huge arrays of bytes, without using a "special"
type, is the thing that should give.
That's not to say you won't be able to come up with some real examples of
situations where it is extremely inconvenient. Engineering is like that.
There's always someone who wants screws with non-standard threads.
--
Free games and programming goodies.
http://www.personal.leeds.ac.uk/~bgy1mm
|
|
0
|
|
|
|
Reply
|
regniztar (3128)
|
9/2/2007 6:33:13 PM
|
|
jacob navia:
> Standard C doesn't have
>
> 1) Any serious i/o. To do anything fast you need system specific stuff.
> 2) Any notion of the keyboard. To handle the keyboard you need system
> specific stuff.
> 3) Any graphics. Ditto.
> 4) No network.
> 5) Not any timers with reasonable accuracy.
Good job so that 99% of algorithms don't need any of the above.
> C is very popular for systems programming but none of those programs
> is written in standard C.
Where possible, I'd hope that they are.
> I am porting the lcc-win IDE and debugger. Written in C but system
> specific. And I do not give a damm about portability of a windows
> debugger to the latest toaster with embedded linux :-)
I don't see what you're smiling about since you've already had a
headache with strlen.
> All this people talking about "Portable standard C" are just talking
> nonsense.
I've written countless fully-portable C programs.
> #include <stdio.h>
> int main(void){printf("hello\n");}
>
> is portable since the errors of printf are NOT specified, so you have no
> way to know what happened if printf returns a negative result, besides
> going into implementation specific stuff!
In the absence of an output error you're guaranteed of the results.
But then how often do we get an output error in such a small program?
0% of the time? Or would it be something considerably bigger like
0.0000000000000000000000000000000000000001% of the time?
Martin
|
|
0
|
|
|
|
Reply
|
warint (199)
|
9/2/2007 6:46:49 PM
|
|
Malcolm:
> What are those ints going to be used for? We don't know, but such a useful
> function would surely find a place in calculating array indices, or
> intermediate values, such as counts, to calculating array indices.
>
> So we need another version
>
> void AddFiveToEachElementsz(size_t *p, size_t len)
>
> The fuse has gone off. That's what the admission of size_t does to your
> code.
Sorry I haven't a clue what you're talking about. Could you please
explain more clearly?
Martin
|
|
0
|
|
|
|
Reply
|
warint (199)
|
9/2/2007 6:50:08 PM
|
|
Ed:
> But, instead of pointless and unfounded insults, let's try a real
> world test for a change. You paste one or two thousand lines of C
> code you've written from your most recent project, and we'll see if
> anyone on the newsgroup can identify any code that's not 100% portable
> C code.
>
> Since you've made the claim that writing 100% portable C code isn't
> just easy, but VERY easy, I'm quite sure you're up to the challenge.
> It's time to put your code where your mouth is.
Ask me to write an algorithm. Or even an algorithm contained in a very
small program. I'd write it efficiently using fully-portable code.
Something along the lines of the Euro Banknote Serial Number Checker.
Martin
|
|
0
|
|
|
|
Reply
|
warint (199)
|
9/2/2007 6:59:57 PM
|
|
Chris:
> Furthermore, the easy-ness of portability varies with the goal of
> the code. Clearly, something like "calculate mortgage payments"
> or "concatenate files specified by argv[] elements" is going to be
> easier than "write an operating system" or "do bitmapped graphics":
> the latter two *require* at least *some* non-portable code.
Let's say for instance that on a particular platform, that an
"unsigned int" contains padding bits (or whatever they call those bits
that don't part-take in indicating what the number is). This could
possibly throw a big spanner in the works for playing around with
bitmaps.
However, it's still not impossible to achieve what you want if you
play around with arrays of "unsigned char". Indeed, the code might be
ugly, but it's definitely possible. And probably fun to write too.
Martin
|
|
0
|
|
|
|
Reply
|
warint (199)
|
9/2/2007 7:02:45 PM
|
|
Martin Wells <warint@eircom.net> writes:
> jacob navia:
[...]
>> #include <stdio.h>
>> int main(void){printf("hello\n");}
>>
>> is portable since the errors of printf are NOT specified, so you have no
>> way to know what happened if printf returns a negative result, besides
>> going into implementation specific stuff!
I assume jacob meant to say "non-portable".
The failure to return a value from main() makes the program less
portable than it could be, since the program is very likely to be
compiled by a compiler that doesn't fully implement C99. Adding a
"return 0;" costs practically nothing and doesn't hurt C99
conformance.
> In the absence of an output error you're guaranteed of the results.
> But then how often do we get an output error in such a small program?
> 0% of the time? Or would it be something considerably bigger like
> 0.0000000000000000000000000000000000000001% of the time?
Output errors happen. Suppose stdout is directed to a file on a
filesystem that has no remaining space. (I was going to give
"./prog > /dev/nosuchdevice" as an example, but that fails in the
calling environment before the program is invoked, at least on my
system.)
For a simple program like this, there's probably no good way to handle
an output error, so ignoring it is probably acceptable. But if I
wanted to be a bit more paranoid, I might check the result of printf()
and print a message to stderr (it's at least possible that stderr is
writable even if stdout isn't). Or at least the program could do
'exit(EXIT_FAILURE);' on an output error, so that whatever entity
invoked it can detect that something went wrong and perform some
cleanup. For example, if only part of the output is written, you
might want to delete the output file altogether rather than leaving an
incorrect partial file lying around.
--
Keith Thompson (The_Other_Keith) kst-u@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"
|
|
0
|
|
|
|
Reply
|
kst-u (21474)
|
9/2/2007 7:20:49 PM
|
|
"Kelsey Bjarnason" <kbjarnason@gmail.com> wrote in message
news:nn9rq4-8cc.ln1@spanky.localhost.net...
> On Sun, 02 Sep 2007 12:54:23 +0000, Richard Heathfield wrote:
>
>> Malcolm McLean said:
>>
>>>
>>> "Richard Heathfield" <rjh@see.sig.invalid> wrote in message
>>> news:6eadnQpTEJCNO0fbnZ2dneKdnZydnZ2d@bt.com...
>>>>
>>>> Indeed. Everyone makes mistakes. To err is human, and all that.
>>>> People are not criticised here for making mistakes, but they *are*
>>>> (rightly) criticised for refusing to acknowledge them or to learn
>>>> from them.
>>>>
>>> It would be nice if that were true.
>>
>> I think it *is* true, by and large. Mistakes *are* pointed out, and
>> rightly so, but to point out a mistake is *not* the same as to
>> criticise the person who made it. I make my fair share of mistakes (or
>> perhaps more!), but when people in clc point this out, I don't feel
>> threatened or intimidated by the fact. On the contrary, I welcome
>> corrections for what they really are - opportunities to learn and to
>> improve my programming.
>
> Yeah, you just tend to make your mistakes so esoteric only about three
> people are qualified to find them, let alone figure out the right way. :)
>
Harald van Dijk found one, I found another, so can you find a third?
--
Free games and programming goodies.
http://www.personal.leeds.ac.uk/~bgy1mm
|
|
0
|
|
|
|
Reply
|
regniztar (3128)
|
9/2/2007 7:21:55 PM
|
|
"Martin Wells" <warint@eircom.net> wrote in message
news:1188759008.401656.243280@r29g2000hsg.googlegroups.com...
> Malcolm:
>
>> What are those ints going to be used for? We don't know, but such a
>> useful
>> function would surely find a place in calculating array indices, or
>> intermediate values, such as counts, to calculating array indices.
>>
>> So we need another version
>>
>> void AddFiveToEachElementsz(size_t *p, size_t len)
>>
>> The fuse has gone off. That's what the admission of size_t does to your
>> code.
>
>
> Sorry I haven't a clue what you're talking about. Could you please
> explain more clearly?
>
Yes.
It the standards problem. As long as every nut will fit every bolt,
everything is simple. Engineer one says "give me a nut", engineer two
supplies it.
Once you allow for more than one standard, there is always trouble.
Engineer one says "give me a quarter inch nut". Engineer two "I can't, I've
only got a nut-making machine that does centimetres". Engineer one, "oh
never mind, I just need to fiddle with this design to make the holes
centimetres rather than quarter inch. Hardly matters. Back to you tomorrow".
sizes and counts are extremely common. Integers that don't ultimately end up
being used in index calculations are maybe a bit rarer, but not so uncommon
either. The function, as supplied, is positively inviting someone to use an
int for an index or size value, if for some reason he needs to add five to
every one of an array of indexes or sizes. We can fix that, by providing a
version that takes size_ts. But now we've just doubled the amount of code in
our system. If it turns out there is some error in the logic, can we
guarantee that both functions will be kept in synch? Maybe in some super, on
the ball, formal methods for eveything shop, but not in any place I've ever
worked.
--
Free games and programming goodies.
http://www.personal.leeds.ac.uk/~bgy1mm
|
|
0
|
|
|
|
Reply
|
regniztar (3128)
|
9/2/2007 7:35:47 PM
|
|
Malcolm McLean wrote:
>
> "Kelsey Bjarnason" <kbjarnason@gmail.com> wrote in message
> news:cl9rq4-8cc.ln1@spanky.localhost.net...
>> On Sat, 01 Sep 2007 20:16:43 +0100, Malcolm McLean wrote:
>>
>>> No, limited experience, Not the same thing as incompetence at all.
>>
>>> If you write say, mainly code to drive GUIs under Windows, you will find
>>> >> that there's little point making much portable. Everything has to be
>>> ripped
>>> up and rewritten whenever the denizens of Redmond decide to realease a
>>> >> new compiler anyway.
>>
>> He said incompetence, and you just demonstrated it.
>>
>> If I were writing such apps, I'd write the body of the code to be as
>> conforming as possible, meaning it is effectively immune to switching to
>> a different OS, compiler, or version of a compiler.
>>
> What you not uncommonly find is that the actual processing that the app
> performs is trivial - maybe it adds a few columns of numbers together and
> produces a report. However the GUI to allow the user to enter these
> numbers, check them, specify which columns to add up, and format the
> report might be very non-trivial. So in fact the portable bit of the code
> is a sum() function and maybe a few histogram or pie chart generators,
> without the graphical part.
You can always write your own wrappers for platform specific GUI
functionality. Things like Java's Swing and wxWidgets prove that it can be
done. Of course it still won't be as portable as C code using only Standard
facilities, *and* it's likely to be a lot of work, but it's possible.
|
|
0
|
|
|
|
Reply
|
santosh.k83 (3969)
|
9/2/2007 7:43:26 PM
|
|
Malcolm McLean wrote, On 02/09/07 20:35:
>
> "Martin Wells" <warint@eircom.net> wrote in message
> news:1188759008.401656.243280@r29g2000hsg.googlegroups.com...
>> Malcolm:
>>
>>> What are those ints going to be used for? We don't know, but such a
>>> useful
>>> function would surely find a place in calculating array indices, or
>>> intermediate values, such as counts, to calculating array indices.
>>>
>>> So we need another version
>>>
>>> void AddFiveToEachElementsz(size_t *p, size_t len)
>>>
>>> The fuse has gone off. That's what the admission of size_t does to your
>>> code.
>>
>>
>> Sorry I haven't a clue what you're talking about. Could you please
>> explain more clearly?
>>
> Yes.
> It the standards problem. As long as every nut will fit every bolt,
> everything is simple. Engineer one says "give me a nut", engineer two
> supplies it.
>
> Once you allow for more than one standard, there is always trouble.
> Engineer one says "give me a quarter inch nut". Engineer two "I can't,
> I've only got a nut-making machine that does centimetres". Engineer one,
> "oh never mind, I just need to fiddle with this design to make the holes
> centimetres rather than quarter inch. Hardly matters. Back to you
> tomorrow".
As discussed last time you used this analogy. Nuts come in multiple
sizes. So if anything it is an argument for having multiple types for
multiple purposes rather than a single type for all purposes. BTW, some
nuts are not hexagonal, for example wing nuts.
> sizes and counts are extremely common.
Yes.
> Integers that don't ultimately
> end up being used in index calculations are maybe a bit rarer,
Or maybe more common. This has not been established.
> but not
> so uncommon either. The function, as supplied, is positively inviting
> someone to use an int for an index or size value, if for some reason he
> needs to add five to every one of an array of indexes or sizes.
A very contrived example. Most of my integer code has been doing things
you would not want to do to sizes or counts. Most of what I have wanted
to do to sizes and counts has been too simple and obvious to want to use
a function.
> We can
> fix that, by providing a version that takes size_ts. But now we've just
> doubled the amount of code in our system. If it turns out there is some
> error in the logic, can we guarantee that both functions will be kept in
> synch? Maybe in some super, on the ball, formal methods for eveything
> shop, but not in any place I've ever worked.
As pointed out, you have the same problem if you want to use the
function with double, float, short or char or any other type.
If you want a language that allows you to avoid it try C++ where you can
use templates.
--
Flash Gordon
|
|
0
|
|
|
|
Reply
|
spam331 (4024)
|
9/2/2007 8:50:37 PM
|
|
Malcolm:
> Once you allow for more than one standard, there is always trouble.
> Engineer one says "give me a quarter inch nut". Engineer two "I can't, I've
> only got a nut-making machine that does centimetres". Engineer one, "oh
> never mind, I just need to fiddle with this design to make the holes
> centimetres rather than quarter inch. Hardly matters. Back to you tomorrow".
If I want to store a number, I use "unsigned". If the number can be
bigger than 65535, I use "long unsigned".
If the number can be negative, I use "int". If it can be outside the
bounds of -32767 to 32767, I use "long int".
That's pretty much it. No need to go delving through a Microsoft
manual, or a Linux manual, or an 8086 manual.
> sizes and counts are extremely common. Integers that don't ultimately end up
> being used in index calculations are maybe a bit rarer, but not so uncommon
> either.
Unsigned integers are the default for me. I only use signed integers
when I want to be able to store negative numbers. "Int syndrome" is to
blame for the prevalence of signed integer types.
> The function, as supplied, is positively inviting someone to use an
> int for an index or size value, if for some reason he needs to add five to
> every one of an array of indexes or sizes.
No, it's not. It's inviting the programmer to supply the function with
a positive number (even 0) indicating how many elements to modify. If
the type of the argument supplied is anything other than "size_t",
then a conversion takes place. If the programmer doesn't know how C
handles conversions, then they should either:
a) Consult a reference guide
or
b) Start drinking
Consistently, the people who are against size_t are putting across the
"incompetence" argument. Don't bitch at the author of the function
just because you missed the day in playschool where they talked about
unsigned integers.
> We can fix that, by providing a
> version that takes size_ts. But now we've just doubled the amount of code in
> our system.
HAVEN'T GOT A CLUE WHAT YOU'RE TALKING ABOUT.
One function is all we need, whose parameter is a size_t. If you use
int instead, then you're a crap programmer, you're shit, you're
incompetant, and you don't know what you're doing.
> If it turns out there is some error in the logic, can we
> guarantee that both functions will be kept in synch? Maybe in some super, on
> the ball, formal methods for eveything shop, but not in any place I've ever
> worked.
No we can't guarantee they'll be in sync, especially since one of them
shouldn't even exist.
Martin
|
|
0
|
|
|
|
Reply
|
warint (199)
|
9/2/2007 9:00:17 PM
|
|
Malcolm McLean wrote:
>
.... snip ...
>
> What you not uncommonly find is that the actual processing that
> the app performs is trivial - maybe it adds a few columns of
> numbers together and produces a report. However the GUI to allow
> the user to enter these numbers, check them, specify which columns
> to add up, and format the report might be very non-trivial. So in
> fact the portable bit of the code is a sum() function and maybe a
> few histogram or pie chart generators, without the graphical part.
Apparently you never write anything computationally complex.
--
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
|
|
0
|
|
|
|
Reply
|
cbfalconer (19183)
|
9/2/2007 10:54:39 PM
|
|
[snips]
On Sun, 02 Sep 2007 01:55:22 +0200, Richard wrote:
>>> It is also a lot easier to find errors in books than to write one.
>>
>> It is even harder to write a good book.
>>
>
> You really are quite a nasty person.
No, he's not.
Schildt, as just one example, wrote The Annotated ANSI C Standard, a book
ostensibly intended to make the ANSI standard clearer and more
approachable. It did so by presenting excerpts from the standard on one
page, then discussing each on the facing page.
Despite this - despite having the relevant portion of the standard staring
him straight in the face while writing the discussion of it - he produced
things which are in some cases simply oversights and the like, but in
other cases actually flat-out wrong, in no way derivable from what he's
supposedly annotating.
For example, in 5.1.2.2, he claims that you can define main as required
for your program, giving the example of void main(void), despite the
facing page - the standard - explicitly stating that no, sorry, this is
not valid.
The book is rampant with such flaws; it is a *bad* book, plain and simple.
Now take Malcolm's book. In terms of explaining algorithms, it might be
perfectly well and good. In terms of doing so _in C_, however, it falls
flat on its face, repeatedly.
He notes, in one place (see his page) "The prefix “str” is reserved by
ANSI". So he *knows* that he's not supposed to use this prefix. He then
proceeds, on the same page (on the web, at least) to define a function
strcount, in direct violation of the rule he, himself, has just explained.
On the same page, he writes " Firstly, the ANSI standard specifies that
strlen() must return a size_t, rather than an integer, to guard against
being passed a string longer than the range of an integer."
Er, no, actually, this does not guard against anything; rather, it simply
allows strlen to return a correct size for a string, if that size exceeds
that which can be stored in an int. However, that aside, he has explained
exactly why the str functions use size_t - because ints simply can't cut
it.
So what does he do? Right; his strcount function returns an int, which he
has already explicitly pointed out is the wrong type, and why.
Any technical book can contain errors. Any can contain mistakes. People
are human, we don't expect perfection from them. Authors, in particular,
walk a fine line between presenting things which are "correct" in the
nit-picking sense, and things which are actually comprehensible to mere
mortals, and they will, at times, likely find themselves sacrificing
absolute strict correctness for clarity and vice versa.
This book, however, presents - in two separate instances in a single
chapter - not simply giving up strict correctness, but going out of its
way to explain a requirement or restriction, then promptly ignoring it
entirely, as if such things simply did not matter when writing code.
The author is obviously well aware of the issues involved; he explicitly
points them out. "str" is reserved. int can't handle the maximum lengths
involved. He documents these... then ignores them.
This is a *bad* book, there are no two ways about it. The flaws in it are
not mere oversights or errors; the author himself admits the code (and
thus the book) is written with his own personal anti-size_t view in mind,
which wouldn't be so bad if he had actually contemplated the effects of
that choice, but it is readily apparent he didn't, nor did he, apparently,
make the risks involved in that decision explicit to the reader.
The result is code that is actively dangerous. Code which discards data,
code which fails in strange and unpredictable ways, code which simply
cannot be used as is, yet which is both sufficiently appealing to
appeal to a novice and sufficiently broken to screw up said novice's
application, without so much as a warning such as "This function can only
handle N bytes of data or corruption will occur" or "your data doesn't
actually matter, so using this function will simply discard it if it feels
like."
It is bad *by design*, because it is not merely a book on algorithms, but
a book on algorithms *and* the author's weird take on proper types,
violation of standard requirements and the like. The author simply
doesn't give a toss about such things and presents this lack of concern as
if it were acceptable practise for a professional - i.e. someone qualified
to write such a book.
It is, in exactly one sense, a good book; it is a good example of how
*not* to do such things. Unfortunately, it seems to lack the appropriate
cover sticker warning the reader of the dangers contained within.
|
|
0
|
|
|
|
Reply
|
kbjarnason (4583)
|
9/2/2007 11:59:35 PM
|
|
>Chris:
>> Furthermore, the easy-ness of portability varies with the goal of
>> the code. Clearly, something like "calculate mortgage payments"
>> or "concatenate files specified by argv[] elements" is going to be
>> easier than "write an operating system" or "do bitmapped graphics":
>> the latter two *require* at least *some* non-portable code.
In article <1188759765.090002.228490@57g2000hsv.googlegroups.com>,
Martin Wells <warint@eircom.net> wrote:
>Let's say for instance that on a particular platform, that an
>"unsigned int" contains padding bits (or whatever they call those bits
>that don't part-take in indicating what the number is). This could
>possibly throw a big spanner in the works for playing around with
>bitmaps.
>
>However, it's still not impossible to achieve what you want if you
>play around with arrays of "unsigned char". Indeed, the code might be
>ugly, but it's definitely possible. And probably fun to write too.
Indeed; and this would be completely portable, up to -- but not
including -- the step where you draw the results on your fancy
bitmapped color display. :-)
Often we (by "we" I mean "I and other people I work with") make
deliberate trades of "giving up some degree of portability for some
degree of performance". Continuing with the above example, we
might work with "unsigned int"s to handle 16 or 32 or 64 bits at
a time (however many are in "unsigned int") instead of restricting
ourselves to "unsigned char". I think it is important to be aware
that one is making such a trade-off, though.
--
In-Real-Life: Chris Torek, Wind River Systems
Salt Lake City, UT, USA (40�39.22'N, 111�50.29'W) +1 801 277 2603
email: forget about it http://web.torek.net/torek/index.html
Reading email is like searching for food in the garbage, thanks to spammers.
|
|
0
|
|
|
|
Reply
|
nospam252 (1722)
|
9/3/2007 3:16:08 AM
|
|
Kelsey Bjarnason wrote:
> Any technical book can contain errors. Any can contain mistakes.
In the last two weeks, I discovered a ... bugette ... an
appendix to a software development book, viz, in the description
of converting a regular expression into a state machine, it
could generate multiple redundant states under a plausible reading
of the algorithm.
The bug has been sitting there for thirteen years. So far as I
know, no-one has ever informed the author, which makes me suspect
that either no-one ever used that algorithm, or if they did, they
also saw the fix.
It would have been nice to have noticed it fourteen years ago,
though.
--
(A.B)* OOPS Hedgehog
"It took a very long time, much longer than the most generous estimates."
- James White, /Sector General/
|
|
0
|
|
|
|
Reply
|
eh (206)
|
9/3/2007 6:01:20 AM
|
|
"Malcolm McLean" <regniztar@btinternet.com> wrote:
> "Martin Wells" <warint@eircom.net> wrote in message
> news:1188759008.401656.243280@r29g2000hsg.googlegroups.com...
> > Malcolm:
> >
> >> The fuse has gone off. That's what the admission of size_t does to your
> >> code.
> >
> > Sorry I haven't a clue what you're talking about. Could you please
> > explain more clearly?
> >
> Yes.
> It the standards problem. As long as every nut will fit every bolt,
> everything is simple. Engineer one says "give me a nut", engineer two
> supplies it.
>
> Once you allow for more than one standard, there is always trouble.
> Engineer one says "give me a quarter inch nut". Engineer two "I can't, I've
> only got a nut-making machine that does centimetres". Engineer one, "oh
> never mind, I just need to fiddle with this design to make the holes
> centimetres rather than quarter inch. Hardly matters. Back to you tomorrow".
And your solution to this problem is to use oil tanker-sized nuts on
office chairs, or office chair-sized nuts on oil tankers. Frankly, I
think you're nuts.
Richard
|
|
0
|
|
|
|
Reply
|
rlb (4118)
|
9/3/2007 7:49:58 AM
|
|
Richard Bos wrote:
> "Malcolm McLean" <regniztar@btinternet.com> wrote:
>
>> "Martin Wells" <warint@eircom.net> wrote in message
>> news:1188759008.401656.243280@r29g2000hsg.googlegroups.com...
>>> Malcolm:
>>>
>>>> The fuse has gone off. That's what the admission of size_t does to your
>>>> code.
>>> Sorry I haven't a clue what you're talking about. Could you please
>>> explain more clearly?
>>>
>> Yes.
>> It the standards problem. As long as every nut will fit every bolt,
>> everything is simple. Engineer one says "give me a nut", engineer two
>> supplies it.
>>
>> Once you allow for more than one standard, there is always trouble.
>> Engineer one says "give me a quarter inch nut". Engineer two "I can't, I've
>> only got a nut-making machine that does centimetres". Engineer one, "oh
>> never mind, I just need to fiddle with this design to make the holes
>> centimetres rather than quarter inch. Hardly matters. Back to you tomorrow".
>
> And your solution to this problem is to use oil tanker-sized nuts on
> office chairs, or office chair-sized nuts on oil tankers. Frankly, I
> think you're nuts.
>
> Richard
This is exactly the problem Malcolm. Your "one size fits all" is
impracticable in the real world: It produces a bloat in all data
structures that do not need 64 bits but can use 16 or even 8.
Note that the ages of all humans in the planet fit into an unsigned
char. There is no need to use 64 when 8 will do.
|
|
0
|
|
|
|
Reply
|
jacob (2538)
|
9/3/2007 7:51:17 AM
|
|
jacob:
> This is exactly the problem Malcolm. Your "one size fits all" is
> impracticable in the real world: It produces a bloat in all data
> structures that do not need 64 bits but can use 16 or even 8.
Oh God I can see where this is going...
> Note that the ages of all humans in the planet fit into an unsigned
> char. There is no need to use 64 when 8 will do
For a compiler writer, you seem to know very little about efficiency.
I myself NEVER use anything smaller than an "int" or "unsigned".
Never. Unless memory consumption is a BIG deal.
The C Standard says that "int" and "unsigned" will be the "natural"
integer types, the quickest ones.
If the Standard Library functions didn't use "char" for strings then
I'd probably use arrays of int or unsigned. That's of course assuming
that I'm not low on memory.
The beauty of the C Standard when it comes to integer types is that
not only are they portable, but they turn out as efficient as possible
on the next platform too.
Only if you need a really big number or a really small negative
number, should you resort to anything bigger than "int" or "unsigned".
Only if memory consumption is a big deal should you resort to anything
smaller.
Of course, there's a few exceptions, like using char to play around
with bytes, or short to play around with small chunks of bytes.
Martin
|
|
0
|
|
|
|
Reply
|
warint (199)
|
9/3/2007 11:40:38 AM
|
|
Martin Wells wrote:
> jacob:
>
>> This is exactly the problem Malcolm. Your "one size fits all" is
>> impracticable in the real world: It produces a bloat in all data
>> structures that do not need 64 bits but can use 16 or even 8.
>
>
> Oh God I can see where this is going...
>
>
>> Note that the ages of all humans in the planet fit into an unsigned
>> char. There is no need to use 64 when 8 will do
>
>
> For a compiler writer, you seem to know very little about efficiency.
>
Arrogance anyone?
> I myself NEVER use anything smaller than an "int" or "unsigned".
> Never. Unless memory consumption is a BIG deal.
>
Yes. "Unless memory consumption is a BIG deal".
If I am doing statistical analysis of age correlated data for
20 million people, I would rather have it as 20MB than as 80MB.
Note that in current CPUs, memory access is one of the main limiting
factors in a program. Memory I/O can slow everything down
because the speed of RAM is snail paced compared to the CPU.
Right now, the ratio of main memory RAM to CPU clock speed is around 10
at least, i.e. doubling the amount of memory used can reduce the
speed of the program by half in some circumstances!
> The C Standard says that "int" and "unsigned" will be the "natural"
> integer types, the quickest ones.
>
This is no longer the case in 64 bit windows: the natural size is 64
bits but int is 32.
> If the Standard Library functions didn't use "char" for strings then
> I'd probably use arrays of int or unsigned. That's of course assuming
> that I'm not low on memory.
>
I repeat: "That's of course assuming I'm not low on memory".
Using 64 bits or 32 bits for an 8 bit character would slow down
operations by a factor of 4 to a factor of 8!
> The beauty of the C Standard when it comes to integer types is that
> not only are they portable, but they turn out as efficient as possible
> on the next platform too.
>
That is why I use the types adapted to the data they hold!
I was pointing out that "one size fits all" attitude would
produce waste of memory space!
> Only if you need a really big number or a really small negative
> number, should you resort to anything bigger than "int" or "unsigned".
>
That is what I was saying, but you are not strong at reading
something BEFORE you start mumbling something like:
> For a compiler writer, you seem to know very little about efficiency.
|
|
0
|
|
|
|
Reply
|
jacob (2538)
|
9/3/2007 11:55:49 AM
|
|
Martin Wells <warint@eircom.net> writes:
> jacob:
>
>> This is exactly the problem Malcolm. Your "one size fits all" is
>> impracticable in the real world: It produces a bloat in all data
>> structures that do not need 64 bits but can use 16 or even 8.
>
>
> Oh God I can see where this is going...
>
>
>> Note that the ages of all humans in the planet fit into an unsigned
>> char. There is no need to use 64 when 8 will do
>
>
> For a compiler writer, you seem to know very little about efficiency.
>
> I myself NEVER use anything smaller than an "int" or "unsigned".
> Never. Unless memory consumption is a BIG deal.
>
> The C Standard says that "int" and "unsigned" will be the "natural"
> integer types, the quickest ones.
Efficiency isn't all about "quickest". Most people dont give a fig if it
takes 11 minutes to 10.5 minutes.
What is endemic though is this complete disregard for optimal data
sizes. It's called bloatware. It's part of the reason Machines are about
1000 times faster than in 1990 yet take the same time bring up a word
processor.
>
> If the Standard Library functions didn't use "char" for strings then
> I'd probably use arrays of int or unsigned. That's of course assuming
> that I'm not low on memory.
>
> The beauty of the C Standard when it comes to integer types is that
> not only are they portable, but they turn out as efficient as possible
> on the next platform too.
>
> Only if you need a really big number or a really small negative
> number, should you resort to anything bigger than "int" or "unsigned".
>
> Only if memory consumption is a big deal should you resort to anything
> smaller.
C programmer should nearly always consider memory use IMO. It's one of
the things which gives C the edge.
I would be horrified if some idiot saved a million records to memory
using a size_t to represent the length in bytes of the records string
UID or somesuch.
Common sense.
|
|
0
|
|
|
|
Reply
|
rgrdev (1814)
|
9/3/2007 12:16:03 PM
|
|
Martin Wells <warint@eircom.net> writes:
> jacob:
>
>> This is exactly the problem Malcolm. Your "one size fits all" is
>> impracticable in the real world: It produces a bloat in all data
>> structures that do not need 64 bits but can use 16 or even 8.
>
>
> Oh God I can see where this is going...
>
>
>> Note that the ages of all humans in the planet fit into an unsigned
>> char. There is no need to use 64 when 8 will do
>
>
> For a compiler writer, you seem to know very little about efficiency.
>
> I myself NEVER use anything smaller than an "int" or "unsigned".
> Never. Unless memory consumption is a BIG deal.
>
> The C Standard says that "int" and "unsigned" will be the "natural"
> integer types, the quickest ones.
>
Efficiency isn't all about "quickest". Most people dont give a fig if it
takes 11 minutes to 10.5 minutes.
What is endemic though is this complete disregard for optimal data
sizes. It's called bloatware. It's part of the reason Machines are about
1000 times faster than in 1990 yet take the same time bring up a word
processor.
>
> If the Standard Library functions didn't use "char" for strings then
> I'd probably use arrays of int or unsigned. That's of course assuming
> that I'm not low on memory.
>
C programmer should nearly always consider memory use IMO. It's one of
the things which gives C the edge.
I would be horrified if some idiot saved a million records to memory
using a size_t to represent the length in bytes of the records string
UID or somesuch.
Common sense.
|
|
0
|
|
|
|
Reply
|
rgrdev (1814)
|
9/3/2007 12:17:07 PM
|
|
Martin Wells <warint@eircom.net> writes:
> jacob:
>
>> This is exactly the problem Malcolm. Your "one size fits all" is
>> impracticable in the real world: It produces a bloat in all data
>> structures that do not need 64 bits but can use 16 or even 8.
>
>
> Oh God I can see where this is going...
>
>
>> Note that the ages of all humans in the planet fit into an unsigned
>> char. There is no need to use 64 when 8 will do
>
>
> For a compiler writer, you seem to know very little about efficiency.
>
> I myself NEVER use anything smaller than an "int" or "unsigned".
> Never. Unless memory consumption is a BIG deal.
>
> The C Standard says that "int" and "unsigned" will be the "natural"
> integer types, the quickest ones.
>
Efficiency isn't all about "quickest". Most people dont give a fig if it
takes 11 minutes to 10.5 minutes.
What is endemic though is this complete disregard for optimal data
sizes. It's called bloatware. It's part of the reason Machines are about
1000 times faster than in 1990 yet take the same time bring up a word
processor.
>
> If the Standard Library functions didn't use "char" for strings then
> I'd probably use arrays of int or unsigned. That's of course assuming
> that I'm not low on memory.
>
C programmers should nearly always consider memory use IMO. It's one of
the things which gives C the edge.
I would be horrified if some idiot saved a million records to memory
using a size_t to represent the length in bytes of the records string
UID or somesuch.
Common sense.
|
|
0
|
|
|
|
Reply
|
rgrdev (1814)
|
9/3/2007 12:21:18 PM
|
|
Richard <rgrdev@gmail.com> writes:
> I would be horrified if some idiot saved a million records to memory
> using a size_t to represent the length in bytes of the records string
> UID or somesuch.
>
> Common sense.
Hmm. Sorry about the double post. (Oh and I probably didnt mean a
million there - but you get the point).
|
|
0
|
|
|
|
Reply
|
rgrdev (1814)
|
9/3/2007 12:23:37 PM
|
|
jacob:
> If I am doing statistical analysis of age correlated data for
> 20 million people, I would rather have it as 20MB than as 80MB.
Brilliant. In such a case, you might opt for an unsigned char. Or if
you were REALLY clever you'd write your own code to manipulate the
bits so that a human age only takes 7 bits. As far as I know, the
oldest recorded and confirmed human was 128 or so, but then I suppose
on exception out of 6 billion isn't too bad.
> Note that in current CPUs, memory access is one of the main limiting
> factors in a program. Memory I/O can slow everything down
> because the speed of RAM is snail paced compared to the CPU.
If a machine is 32-bit, shouldn't it access a 32-bit number quicker
than an 8-bit number?
> Right now, the ratio of main memory RAM to CPU clock speed is around 10
> at least, i.e. doubling the amount of memory used can reduce the
> speed of the program by half in some circumstances!
See the point I made just above.
> > The C Standard says that "int" and "unsigned" will be the "natural"
> > integer types, the quickest ones.
>
> This is no longer the case in 64 bit windows: the natural size is 64
> bits but int is 32.
This is a shortcoming of Microsoft. One of many.
> > If the Standard Library functions didn't use "char" for strings then
> > I'd probably use arrays of int or unsigned. That's of course assuming
> > that I'm not low on memory.
>
> I repeat: "That's of course assuming I'm not low on memory".
>
> Using 64 bits or 32 bits for an 8 bit character would slow down
> operations by a factor of 4 to a factor of 8!
Again see my argument above. It should be faster.
> > The beauty of the C Standard when it comes to integer types is that
> > not only are they portable, but they turn out as efficient as possible
> > on the next platform too.
>
> That is why I use the types adapted to the data they hold!
>
> I was pointing out that "one size fits all" attitude would
> produce waste of memory space!
Yes, you'd waste 3 bytes for every byte, but it should be faster. If
the 3 bytes waste is too much for you, then use an unsigned char, or
manipulate individual bits directly with your own code.
Martin
|
|
0
|
|
|
|
Reply
|
warint (199)
|
9/3/2007 1:18:07 PM
|
|
Martin Wells <warint@eircom.net> writes:
> jacob:
>
>> If I am doing statistical analysis of age correlated data for
>> 20 million people, I would rather have it as 20MB than as 80MB.
>
>
> Brilliant. In such a case, you might opt for an unsigned char. Or if
> you were REALLY clever you'd write your own code to manipulate the
> bits so that a human age only takes 7 bits. As far as I know, the
> oldest recorded and confirmed human was 128 or so, but then I suppose
> on exception out of 6 billion isn't too bad.
>
>
>> Note that in current CPUs, memory access is one of the main limiting
>> factors in a program. Memory I/O can slow everything down
>> because the speed of RAM is snail paced compared to the CPU.
>
>
> If a machine is 32-bit, shouldn't it access a 32-bit number quicker
> than an 8-bit number?
No. Why? Or maybe. It depends .... OT.
What is NOT off topic though is the strategic use of types to represent
data. And programming in C to TRY and reduce memory consumption can
never be a bad thing UNLESS the results result in undefined
behaviour. And in a DEFINED limitation of say "name is never longer than
32 chars" then you I personally would never store that length as 32 or
64 bit when an array of 16 bits or 8 bits would do and save potentially
megabytes of memory.
>
>
>> Right now, the ratio of main memory RAM to CPU clock speed is around 10
>> at least, i.e. doubling the amount of memory used can reduce the
>> speed of the program by half in some circumstances!
>
>
> See the point I made just above.
>
>
>> > The C Standard says that "int" and "unsigned" will be the "natural"
>> > integer types, the quickest ones.
>>
>> This is no longer the case in 64 bit windows: the natural size is 64
>> bits but int is 32.
>
>
> This is a shortcoming of Microsoft. One of many.
>
>
>> > If the Standard Library functions didn't use "char" for strings then
>> > I'd probably use arrays of int or unsigned. That's of course assuming
>> > that I'm not low on memory.
>>
>> I repeat: "That's of course assuming I'm not low on memory".
>>
>> Using 64 bits or 32 bits for an 8 bit character would slow down
>> operations by a factor of 4 to a factor of 8!
>
>
> Again see my argument above. It should be faster.
>
>
>> > The beauty of the C Standard when it comes to integer types is that
>> > not only are they portable, but they turn out as efficient as possible
>> > on the next platform too.
>>
>> That is why I use the types adapted to the data they hold!
>>
>> I was pointing out that "one size fits all" attitude would
>> produce waste of memory space!
>
>
> Yes, you'd waste 3 bytes for every byte, but it should be faster. If
> the 3 bytes waste is too much for you, then use an unsigned char, or
> manipulate individual bits directly with your own code.
>
> Martin
>
--
|
|
0
|
|
|
|
Reply
|
rgrdev (1814)
|
9/3/2007 1:51:31 PM
|
|
Martin Wells wrote:
> If a machine is 32-bit, shouldn't it access a 32-bit number quicker
> than an 8-bit number?
That depends on the machine.
No-one really cares, anyway, not about /a/ 32-bit number. In the case
of Jacob's 20 million people, the question should be whether it's
faster to access 20 million ints or twenty million bytes -- at which
point, such atopical things as caches (presence and size of) and
disc speed (data for the loading of) may matter more than how long
it takes for the machine to mask out the upper 24 bits of a value.
--
Chris "somebody stop me" Dollin
Hewlett-Packard Limited Cain Road, Bracknell, registered no:
registered office: Berks RG12 1HN 690597 England
|
|
0
|
|
|
|
Reply
|
chris.dollin (1683)
|
9/3/2007 1:56:35 PM
|
|
Chris Dollin wrote:
> Martin Wells wrote:
>
>> If a machine is 32-bit, shouldn't it access a 32-bit number quicker
>> than an 8-bit number?
>
> That depends on the machine.
>
> No-one really cares, anyway, not about /a/ 32-bit number. In the case
> of Jacob's 20 million people, the question should be whether it's
> faster to access 20 million ints or twenty million bytes -- at which
> point, such atopical things as caches (presence and size of) and
> disc speed (data for the loading of) may matter more than how long
> it takes for the machine to mask out the upper 24 bits of a value.
>
In all cases, caches or not, i/o of 20MB is faster than i/o of 80MB.
It *could* be that disk caches go to 80MB and then it would be the same.
Not with main memory though. Main memory caches go into the MB range at
most, and L1 caches are even smaller.
Besides there are other effects to take into consideration.
Normally, machines load data from memory into a cache line
of 32 or 64 bytes, i.e. you read 32 bytes at a time.
Using sparingly memory, for instance making
your structure fit into 32 bytes, will make it load in a single
read operation into the L1 cache. Bigger structures take MUCH more
time since 2 or more reads are necessary...
The general point I want to make is that we have to use the correct type
for the data and situation we are working with.
It would be a bad situation where we would have just
"int with 64 bits"
and we would use int for characters, shorts, etc etc, wasting
an enormous space for nothing at each structure we would use.
True, everything would be much simpler (this is the reason why
Malcolm advocates this I think), but the lost of flexibility would
be enormous.
Besides, in small machines, C would not even run: it wouldn't have
enough RAM to load the program!
|
|
0
|
|
|
|
Reply
|
jacob (2538)
|
9/3/2007 2:12:11 PM
|
|
jacob navia <jacob@jacob.remcomp.fr> writes:
> Chris Dollin wrote:
>> Martin Wells wrote:
>>
>>> If a machine is 32-bit, shouldn't it access a 32-bit number quicker
>>> than an 8-bit number?
>>
>> That depends on the machine.
>>
>> No-one really cares, anyway, not about /a/ 32-bit number. In the case
>> of Jacob's 20 million people, the question should be whether it's
>> faster to access 20 million ints or twenty million bytes -- at which
>> point, such atopical things as caches (presence and size of) and
>> disc speed (data for the loading of) may matter more than how long
>> it takes for the machine to mask out the upper 24 bits of a value.
>>
>
> In all cases, caches or not, i/o of 20MB is faster than i/o of 80MB.
>
Never let real world pollute the nirvana of c.l.c
If its not compilable on a DeepThought Nippon 0.2sxxyy Hiroshima
vibrator circuit then it's crap C. Never forget that.
|
|
0
|
|
|
|
Reply
|
rgrdev (1814)
|
9/3/2007 2:28:13 PM
|
|
jacob navia wrote:
> Chris Dollin wrote:
>> Martin Wells wrote:
>>
>>> If a machine is 32-bit, shouldn't it access a 32-bit number quicker
>>> than an 8-bit number?
>>
>> That depends on the machine.
>>
>> No-one really cares, anyway, not about /a/ 32-bit number. In the case
>> of Jacob's 20 million people, the question should be whether it's
>> faster to access 20 million ints or twenty million bytes -- at which
>> point, such atopical things as caches (presence and size of) and
>> disc speed (data for the loading of) may matter more than how long
>> it takes for the machine to mask out the upper 24 bits of a value.
>
> In all cases, caches or not, i/o of 20MB is faster than i/o of 80MB.
`disc speed (data for the loading of)`.
--
Chris "already" Dollin
Hewlett-Packard Limited registered office: Cain Road, Bracknell,
registered no: 690597 England Berks RG12 1HN
|
|
0
|
|
|
|
Reply
|
chris.dollin (1683)
|
9/3/2007 2:31:01 PM
|
|
[snips]
On Sun, 02 Sep 2007 19:00:43 +0100, Malcolm McLean wrote:
>> If I were writing such apps, I'd write the body of the code to be as
>> conforming as possible, meaning it is effectively immune to switching to
>> a different OS, compiler, or version of a compiler.
>>
> What you not uncommonly find is that the actual processing that the app
> performs is trivial - maybe it adds a few columns of numbers together and
> produces a report.
Excuse?
Right now I'm working on a chess app; virtually all the code is
computational, with nigh-on nil for user interaction.
Recently I've written reporting apps - log processing, for example - which
read and process gigabytes of data, then produce web pages delineating
the results. No user interaction at all.
In fact, in all the coding I've ever done, the vast majority of it was
code to actually _do_ things, which means the code for processing
outweighs the code for interaction by a very large margin.
If you constrain yourself to nothing but toy programs, you'll get a toy
program view of the universe. We don't constrain ourselves this way; we
actually work on programs with some meat to them.
|
|
0
|
|
|
|
Reply
|
kbjarnason (4583)
|
9/3/2007 4:29:52 PM
|
|
On Mon, 03 Sep 2007 06:01:20 +0000, Chris Dollin wrote:
> Kelsey Bjarnason wrote:
>
>> Any technical book can contain errors. Any can contain mistakes.
>
> In the last two weeks, I discovered a ... bugette ... an
> appendix to a software development book, viz, in the description
> of converting a regular expression into a state machine, it
> could generate multiple redundant states under a plausible reading
> of the algorithm.
>
> The bug has been sitting there for thirteen years. So far as I
> know, no-one has ever informed the author, which makes me suspect
> that either no-one ever used that algorithm, or if they did, they
> also saw the fix.
>
> It would have been nice to have noticed it fourteen years ago,
> though.
Indeed. As I said - any book can contain errors, and that does not
_necessarily_ reflect poorly upon the book or the author. Authors are
human, tolerance is granted - to a point.
There is a fine line between simple human fallibility and a complete
disregard for anything approaching correctness, and Malcolm, IMO, pole
vaults across that line with abandon.
|
|
0
|
|
|
|
Reply
|
kbjarnason (4583)
|
9/3/2007 5:18:43 PM
|
|
[snips]
On Sun, 02 Sep 2007 20:21:55 +0100, Malcolm McLean wrote:
> Harald van Dijk found one, I found another, so can you find a third?
Actually, I believe I have pointed out errors in stuff posted by Good
Mister Heathfield on more than one occasion.
|
|
0
|
|
|
|
Reply
|
kbjarnason (4583)
|
9/3/2007 5:20:28 PM
|
|
[snips]
On Sun, 02 Sep 2007 19:33:13 +0100, Malcolm McLean wrote:
>> 1) Forcing 16-bit implementations to limit allocations to 32767 or fewer
>> bytes
> Or forcing someone in the unusual situation of allocating more than half of
> the address space in one go into using an unusual type.
Say what? There's nothing unusual about size_t; it has existed for
nigh-on two decades.
> Engineering doesn't usually offer perfect solutions.
Correct. Your "engineering" takes a perfectly viable, if not perfect
solution and breaks it for no benefit other than to make you happy.
> If you want to
> simulataneously have signed arithemetic, an efficient integer
> representation, and use all bits of the integer, something has got to
> give.
Where does C guarantee anything about "use all bits of the integer"?
What, you've never heard of "value bits"?
So what we're dealing with here is not the issues you cite, but rather two
issues:
1) Having an efficient (signed or sign-able) integer type
2) Having a type capable of doing the necessary jobs
These two are, demonstrably, not the same thing, so there have to be at
least two types. We have those: int and size_t.
See how that works? Two requirements, two types.
> The ability to manipulate huge arrays of bytes, without using a
> "special" type, is the thing that should give.
Works for me. Oh, wait, we *do* have a special type; it's called size_t.
The very thing you want to eradicate. But you're arguing that we _need_
such a thing here. Can't have it both ways.
> That's not to say you
> won't be able to come up with some real examples of situations where it
> is extremely inconvenient. Engineering is like that. There's always
> someone who wants screws with non-standard threads.
And in this case, that would be you, trying to subvert something which
works well enough to be useful, which has been used for 17 or more years
*precisely because* it is useful, all because it offends some weird
personal sense of rightness.
Leave the personal aesthetics out of it and present a cogent objective
argument for getting rid of the type... *without* either breaking reams of
existing code or imposing limits which don't currently exist - such as no
longer being able to do perfectly legitimate allocations or requiring the
implementation to produce wildly inefficient results.
|
|
0
|
|
|
|
Reply
|
kbjarnason (4583)
|
9/3/2007 5:29:28 PM
|
|
Kelsey Bjarnason said:
> [snips]
>
> On Sun, 02 Sep 2007 20:21:55 +0100, Malcolm McLean wrote:
>
>> Harald van Dijk found one, I found another, so can you find a third?
>
> Actually, I believe I have pointed out errors in stuff posted by Good
> Mister Heathfield on more than one occasion.
I don't doubt it, for I am far from infallible - but I think Malcolm was
referring to the program I showed upthread as being a (mildly flawed)
example of a program that seems portable on the surface, but which
contains a handful of non-portable assumptions.
Harald van Dijk found a bug in the code. Malcolm claims he found
another, but I can't find any reference to it. Malcolm /may/ have meant
that he has identified one of the non-portable assumptions.
--
Richard Heathfield <http://www.cpax.org.uk>
Email: -www. +rjh@
Google users: <http://www.cpax.org.uk/prg/writings/googly.php>
"Usenet is a strange place" - dmr 29 July 1999
|
|
0
|
|
|
|
Reply
|
rjh (10789)
|
9/3/2007 5:41:30 PM
|
|
Martin Wells wrote:
> jacob:
>
>> This is exactly the problem Malcolm. Your "one size fits all" is
>> impracticable in the real world: It produces a bloat in all data
>> structures that do not need 64 bits but can use 16 or even 8.
>
>
> Oh God I can see where this is going...
>
>
>> Note that the ages of all humans in the planet fit into an unsigned
>> char. There is no need to use 64 when 8 will do
>
>
> For a compiler writer, you seem to know very little about efficiency.
>
> I myself NEVER use anything smaller than an "int" or "unsigned".
> Never. Unless memory consumption is a BIG deal.
>
I guess you've never written a device driver....
--
Ian Collins.
|
|
0
|
|
|
|
Reply
|
ian-news (9881)
|
9/3/2007 7:28:47 PM
|
|
On Tue, 04 Sep 2007 07:28:47 +1200, Ian Collins wrote:
>> I myself NEVER use anything smaller than an "int" or "unsigned".
>> Never. Unless memory consumption is a BIG deal.
>>
> I guess you've never written a device driver....
I suspect most of us haven't. I've been sick enough to write them in
shell script, though.
B.
|
|
0
|
|
|
|
Reply
|
nntp550 (4244)
|
9/3/2007 7:31:24 PM
|
|
"CBFalconer" <cbfalconer@yahoo.com> wrote in message
news:46DB3F2F.BA59ADD5@yahoo.com...
> Malcolm McLean wrote:
>>
> ... snip ...
>>
>> What you not uncommonly find is that the actual processing that
>> the app performs is trivial
>
> Apparently you never write anything computationally complex.
>
Some people can't read. "Not uncommonly" implies that there are some apps
for which this is not true. Of course there are.
However more often than not the complexity of the user interface determines
the amount of effort required to write a program, for desktop apps at least.
Most of what we want to do with computers is computationally quite trivial.
The difficulty is in presenting the information to the user and letting him
manipulate it in an intuitive way.
--
Free games and programming goodies.
http://www.personal.leeds.ac.uk/~bgy1mm
|
|
0
|
|
|
|
Reply
|
regniztar (3128)
|
9/3/2007 8:01:33 PM
|
|
Martin Wells <warint@eircom.net> writes:
[...]
> The C Standard says that "int" and "unsigned" will be the "natural"
> integer types, the quickest ones.
It says "natural"; it does *not* say "quickest".
C99 6.2.5p5:
A "plain" int object has the natural size suggested by the
architecture of the execution environment (large enough to contain
any value in the range INT_MIN to INT_MAX as defined in the header
<limits.h>).
--
Keith Thompson (The_Other_Keith) kst-u@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"
|
|
0
|
|
|
|
Reply
|
kst-u (21474)
|
9/3/2007 8:02:30 PM
|
|
"Richard Heathfield" <rjh@see.sig.invalid> wrote in message
news:aIWdneaw-cI420HbnZ2dnUVZ8vqdnZ2d@bt.com...
> Kelsey Bjarnason said:
>
>> [snips]
>>
>> On Sun, 02 Sep 2007 20:21:55 +0100, Malcolm McLean wrote:
>>
>>> Harald van Dijk found one, I found another, so can you find a third?
>>
>> Actually, I believe I have pointed out errors in stuff posted by Good
>> Mister Heathfield on more than one occasion.
>
> I don't doubt it, for I am far from infallible - but I think Malcolm was
> referring to the program I showed upthread as being a (mildly flawed)
> example of a program that seems portable on the surface, but which
> contains a handful of non-portable assumptions.
>
> Harald van Dijk found a bug in the code. Malcolm claims he found
> another, but I can't find any reference to it. Malcolm /may/ have meant
> that he has identified one of the non-portable assumptions.
>
If presented as a portable program that will produce correct output on any
conforming implementation, it is bugged, because an array of UCHAR_MAX is
not guaranteed to fit in available stack space, sorry, automatic memory.
However if you restrict it to 8 bit char platforms, by far the most common,
it is OK.
--
Free games and programming goodies.
http://www.personal.leeds.ac.uk/~bgy1mm
|
|
0
|
|
|
|
Reply
|
regniztar (3128)
|
9/3/2007 8:05:47 PM
|
|
"jacob navia" <jacob@jacob.remcomp.fr> wrote in message
news:46dc167a$0$27369$ba4acef3@news.orange.fr...
> Chris Dollin wrote:
> True, everything would be much simpler (this is the reason why
> Malcolm advocates this I think), but the lost of flexibility would
> be enormous.
>
> Besides, in small machines, C would not even run: it wouldn't have
> enough RAM to load the program!
>
int would be 64 bits. However char would still be an octet and short would
be 16 bits. In practical terms we will also have to introduce a 32 bit type.
However the fact they are not called "int" discourages people from using
them, unless they really need the extra speed or memory efficiency.
The software problem is not usually that processors are not fast enough. It
is that software modules are not sufficiently standardised, leading to
endless reduplication of effort, and erros as parts are fitted together.
However 64 bit ints are not the perfect solution, in the sense that there
are no good arguments agiant them. One of which is that the raison d' etre
of C is a very efficient language. If int is not in fact the most efficent
integer type, that is a big sacrifice to make. However rewritng everything
with size_t's isn't going to solve that problem. There will still be lots of
64 integers in play, but everything else will break, as we have two
standards for a general-purpose integer.
--
Free games and programming goodies.
http://www.personal.leeds.ac.uk/~bgy1mm
|
|
0
|
|
|
|
Reply
|
regniztar (3128)
|
9/3/2007 8:20:09 PM
|
|
On Mon, 03 Sep 2007 21:01:33 +0100, Malcolm McLean wrote:
> "CBFalconer" <cbfalconer@yahoo.com> wrote in message
> news:46DB3F2F.BA59ADD5@yahoo.com...
>> Malcolm McLean wrote:
>>>
>> ... snip ...
>>>
>>> What you not uncommonly find is that the actual processing that
>>> the app performs is trivial
>>
>> Apparently you never write anything computationally complex.
>>
> Some people can't read. "Not uncommonly" implies that there are some apps
> for which this is not true. Of course there are.
The way you wrote it implies that this is in fact commonplace, to find
these apps which do significant interaction and next to zero processing.
Real-world experience in coding many applications of many different types
argues otherwise; apps do a lot of processing and very little interaction,
though the requirements of that interaction may be complex and require
extensive interfaces.
> However more often than not the complexity of the user interface
> determines the amount of effort required to write a program, for desktop
> apps at least.
Really. So a UI which involves little more than, say, calling an
OS-provided file selector dialog - i.e. a very simple UI - implies that
the code which encrypts the selected file requires almost no effort.
> Most of what we want to do with computers is
> computationally quite trivial.
Says who? Most of what I want to do with computers is computationally
very intensive, but requires little to no user interaction. Simple
example: a chess program. User interaction is very low compared to the
actual effort that goes into the positional analysis. So low, in fact,
the program only occasionally checks for any user interaction at all.
> The difficulty is in presenting the
> information to the user and letting him manipulate it in an intuitive
> way.
That is certainly _a_ challenge. It is by no means the only one.
|
|
0
|
|
|
|
Reply
|
kbjarnason (4583)
|
9/3/2007 8:31:06 PM
|
|
Malcolm McLean said:
<snip>
> If presented as a portable program that will produce correct output on
> any conforming implementation, it is bugged, because an array of
> UCHAR_MAX is not guaranteed to fit in available stack space, sorry,
> automatic memory. However if you restrict it to 8 bit char platforms,
> by far the most common, it is OK.
Thank you for clarifying. That is indeed one of the portability issues
that I knew about when posting that code - i.e. it was one of my
illustrations.
There are at least a couple of others.
--
Richard Heathfield <http://www.cpax.org.uk>
Email: -www. +rjh@
Google users: <http://www.cpax.org.uk/prg/writings/googly.php>
"Usenet is a strange place" - dmr 29 July 1999
|
|
0
|
|
|
|
Reply
|
rjh (10789)
|
9/3/2007 9:06:38 PM
|
|
Keith:
> It says "natural"; it does *not* say "quickest".
Yes I realised that at the time of posting. I take "natural" to imply
that it's the quickest type for doing arithmetic on and so forth.
....I mean they'd hardly make the "natural" type slower than another
type.
Martin
|
|
0
|
|
|
|
Reply
|
warint (199)
|
9/3/2007 9:12:42 PM
|
|
Malcolm McLean wrote, On 03/09/07 21:20:
>
> "jacob navia" <jacob@jacob.remcomp.fr> wrote in message
> news:46dc167a$0$27369$ba4acef3@news.orange.fr...
>> Chris Dollin wrote:
>> True, everything would be much simpler (this is the reason why
>> Malcolm advocates this I think), but the lost of flexibility would
>> be enormous.
>>
>> Besides, in small machines, C would not even run: it wouldn't have
>> enough RAM to load the program!
>>
> int would be 64 bits. However char would still be an octet and short
> would be 16 bits. In practical terms we will also have to introduce a 32
> bit type.
So you do want the standard changed. That is a discussion for
comp.std.c, although I doubt they will be any more impressed with your
ideas than people are here.
> However the fact they are not called "int" discourages people from using
> them, unless they really need the extra speed or memory efficiency.
Well, I really need SW developers to use the memory and speed efficiency
because my expensive company notebook is regularly running at 96% memory
usage and very high processor usage and it is not that uncommon for
responsiveness to suffer as a result. So *I* need all major SW
developers for PCs to use the most efficient type and don't want them
discouraged from doing it because it is some new-fangled type than
Malcolm invented but others did not want.
> The software problem is not usually that processors are not fast enough.
No, but one of the problems is that SW is too slow and memory hungry.
> It is that software modules are not sufficiently standardised, leading
> to endless reduplication of effort, and erros as parts are fitted together.
Strange that I am managing to fit together several non-standard
libraries to do the bulk of a complex project. I've probably written
under 10% of the total code in said project.
> However 64 bit ints are not the perfect solution,
You've got that right.
> in the sense that
> there are no good arguments agiant them.
What, none of the arguments used by Intel which I've pointed you at and
you have not addressed are good? How about the arguments you have been
pointed at by those responsible for the Unix standard that you have not
dealt with?
> One of which is that the raison
> d' etre of C is a very efficient language. If int is not in fact the
> most efficent integer type, that is a big sacrifice to make.
Then we had better stick with 32 bit int because that is what Intel say
is most efficient on their spanking new high end 64 bit processors.
> However
> rewritng everything with size_t's isn't going to solve that problem.
> There will still be lots of 64 integers in play, but everything else
> will break, as we have two standards for a general-purpose integer.
No, we have one standard for a general purpose integer, one standard for
a general purpose unsigned integer, and one standard for sizes and
indexes. So what you think is a second general purpose integer type
isn't but something you did not even consider is. Perhaps you need to
learn a bit more about C before commenting on it since you still do not
seem to understand it.
--
Flash Gordon
|
|
0
|
|
|
|
Reply
|
spam331 (4024)
|
9/3/2007 9:35:04 PM
|
|
[snips]
On Mon, 03 Sep 2007 21:06:38 +0000, Richard Heathfield wrote:
> Thank you for clarifying. That is indeed one of the portability issues
> that I knew about when posting that code - i.e. it was one of my
> illustrations.
In a *perfect* example of non-infallibility, I managed to brain fart from
"stack" to "fifo", rather than "lifo" - and have this caught by
a sharp-eyed reader.
Just goes to show, ain't nobody prefect. :)
Also goes to show why having a competent editor is probably a good idea
for an author.
|
|
0
|
|
|
|
Reply
|
kbjarnason (4583)
|
9/3/2007 10:25:17 PM
|
|
Flash:
> Then we had better stick with 32 bit int because that is what Intel say
> is most efficient on their spanking new high end 64 bit processors.
Then why are they calling them 64-Bit processors? I can use arrays of
unsigned char's in conjunction with bitwise operators to give the
illusion of 256-Bit numbers on any machine... but that doesn't mean
I'm gonna go calling the machine 256-Bit.
Many 32-Bit machines also have 16-Bit registers, however the 32-Bit
ones are (naturally) more efficient. If the same goes for these
alleged 64-Bit machines, then they should be called 32-Bit.
Martin
|
|
0
|
|
|
|
Reply
|
warint (199)
|
9/3/2007 11:52:26 PM
|
|
Martin Wells <warint@eircom.net> writes:
> Flash:
>
>> Then we had better stick with 32 bit int because that is what Intel say
>> is most efficient on their spanking new high end 64 bit processors.
>
> Then why are they calling them 64-Bit processors?
Probably because they have 64-bit addresses.
[...]
>
> Many 32-Bit machines also have 16-Bit registers, however the 32-Bit
> ones are (naturally) more efficient. If the same goes for these
> alleged 64-Bit machines, then they should be called 32-Bit.
The "bitness" of a processor has always been a vague concept. There's
a real difference between a processor that can address 2**32 bytes of
(virtual) memory and one that can address 2**64 bytes, even if the
recommended size of int is the same on both.
--
Keith Thompson (The_Other_Keith) kst-u@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"
|
|
0
|
|
|
|
Reply
|
kst-u (21474)
|
9/4/2007 12:17:28 AM
|
|
Malcolm McLean wrote:
>
.... snip ...
>
> If presented as a portable program that will produce correct
> output on any conforming implementation, it is bugged, because an
> array of UCHAR_MAX is not guaranteed to fit in available stack
> space, sorry, automatic memory. However if you restrict it to 8
> bit char platforms, by far the most common, it is OK.
>From which I gather that you wouldn't trust a system with CHAR_BIT
set to 9 or 10?
--
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
|
|
0
|
|
|
|
Reply
|
cbfalconer (19183)
|
9/4/2007 12:23:46 AM
|
|
Flash Gordon wrote:
>
> What, none of the arguments used by Intel which I've pointed you at and
> you have not addressed are good? How about the arguments you have been
> pointed at by those responsible for the Unix standard that you have not
> dealt with?
>
Notice he always avoids responding when these are mentioned. This tends
to the the usual behavior of a troll.
--
Ian Collins.
|
|
0
|
|
|
|
Reply
|
ian-news (9881)
|
9/4/2007 4:59:30 AM
|
|
Martin Wells wrote, On 04/09/07 00:52:
> Flash:
>
>> Then we had better stick with 32 bit int because that is what Intel say
>> is most efficient on their spanking new high end 64 bit processors.
>
> Then why are they calling them 64-Bit processors?
Because they are 64 bit processors.
> I can use arrays of
> unsigned char's in conjunction with bitwise operators to give the
> illusion of 256-Bit numbers on any machine... but that doesn't mean
> I'm gonna go calling the machine 256-Bit.
>
> Many 32-Bit machines also have 16-Bit registers, however the 32-Bit
> ones are (naturally) more efficient. If the same goes for these
> alleged 64-Bit machines, then they should be called 32-Bit.
I believe the main reason for not having a 64 bit int is probably memory
bandwidth and bloat meaning that even though the ALU is as fast for 64
bit numbers as 32 bit numbers overall performance of 64 bit numbers is
slower.
--
Flash Gordon
|
|
0
|
|
|
|
Reply
|
spam331 (4024)
|
9/4/2007 7:41:00 AM
|
|
On Thu, 30 Aug 2007 15:58:56 +1200, Ian Collins wrote:
> jacob navia wrote:
>> Richard Tobin wrote:
>>> In article <lnhcmivvtl.fsf@nuthaus.mib.org>,
>>> Keith Thompson <kst-u@mib.org> wrote:
>>>
>>>> It's better to fix the code. It's even better to write it correctly
>>>> in the first place.
>>>
>>> But int s = sizeof(char *) is not broken, even though sizeof() returns
>>> a size_t.
>>>
>>> -- Richard
>>
>> If we use size_t everywhere, it is an UNSIGNED quantity.
>> This means that comparisons with signed quantities will provoke
>> other warnings, etc etc.
>>
>> int s = strlen(str) is NOT broken.
>
> Why would you want to assign an unsigned value to an int? Why do you
> think it makes sense to have a negative size?
That's what I thought on seeing the type of the second argument to
fgets.
(What happens when I call fgets(s, -3, stream)? The behavior isn't
undefined by omission because the Standard does specify what will
happen. Too bad that it is a logically impossible thing. (Unless
we interpret it in a creative way and conclude that it should
ungetc() the characters *(s - 1), *(s - 2) and so on down to
*(s - 6)...)
--
Army1987 (Replace "NOSPAM" with "email")
No-one ever won a game by resigning. -- S. Tartakower
|
|
0
|
|
|
|
Reply
|
army1987 (668)
|
9/4/2007 3:05:21 PM
|
|
On Thu, 30 Aug 2007 05:29:26 -0400, CBFalconer wrote:
> jacob navia wrote:
>>
> ... snip ...
>>
>> Because that int is used in many other contexts later, for instance
>> comparing it with other integers.
>>
>> int len = strlen(str);
>>
>> for (i=0; i<len; i++) {
>> /// etc
>> }
>>
>> The i<len comparison would provoke a warning if len is unsigned...
>
> I fail to see any reason why that 'i' should not be declared as
> unsigned. Well, maybe extreme laziness.
Because an idiot programmer could write unsigned i;
for (i--; i >= 0; i--) and disasters would happen.
(In particular, I did this particular mistake the first time I
ever used a C compiler.)
Of course using while (i--) would do exactly the same, but it also
works with unsigned types.
--
Army1987 (Replace "NOSPAM" with "email")
No-one ever won a game by resigning. -- S. Tartakower
|
|
0
|
|
|
|
Reply
|
army1987 (668)
|
9/4/2007 3:09:15 PM
|
|
On Sat, 01 Sep 2007 21:28:59 +0100, Malcolm McLean wrote:
>
> "Peter J. Holzer" <hjp-usenet2@hjp.at> wrote in message
> news:slrnfdjgv5.68a.hjp-usenet2@zeno.hjp.at...
>>
>> and the admission of long, double, long long or any other type.
>>
>> Let's face it, admitting types to C was a mistake.
>> We should go back to B.
>>
> The campaign for 64 bit ints wants int to be 64 bits. Then basically it's
> ints for everything - no need for unsigned, 63 bits hold a number large
> enough to count most things. Other types will be kept for special purposes.
Why should I waste 64 bits to store a flag variable, a value which
can either be a character or EOF, or an enumeration constant, or
the return type of main(), or ...
--
Army1987 (Replace "NOSPAM" with "email")
No-one ever won a game by resigning. -- S. Tartakower
|
|
0
|
|
|
|
Reply
|
army1987 (668)
|
9/4/2007 3:38:43 PM
|
|
Army:
> > I fail to see any reason why that 'i' should not be declared as
> > unsigned. Well, maybe extreme laziness.
>
> Because an idiot programmer could write unsigned i;
> for (i--; i >= 0; i--) and disasters would happen.
> (In particular, I did this particular mistake the first time I
> ever used a C compiler.)
> Of course using while (i--) would do exactly the same, but it also
> works with unsigned types.
That's still no reason to use signed types when we shouldn't. We don't
accomodate incompetence. Anyway, i >= 0 should yield a warning if i is
unsigned.
Martin
|
|
0
|
|
|
|
Reply
|
warint (199)
|
9/4/2007 3:40:13 PM
|
|
In article <46d89ec6$0$5095$ba4acef3@news.orange.fr>,
jacob navia <jacob@jacob.remcomp.fr> writes:
> Craig Gullixson wrote:
>> In article <46d87532$0$5072$ba4acef3@news.orange.fr>,
>> jacob navia <jacob@jacob.remcomp.fr> writes:
>>> Ian Collins wrote:
>>>> jacob navia wrote:
>>>>> int Strlen_i(char *s)
>>>>> {
>>>>> char *start=s;
>>>>> while (*s)
>>>>> s++;
>>>>> return s-start;
>>>>> }
>>>>> #define strlen Strlen_i;
>>>>>
>>>> You really should bite the bullet and fix the code.
>>>>
>>> If aint'broken do not fix it
>>>
>>
>>
>> But it *is* broken as far as the C standard is concerned.
>>
>
> Look, it is not the C standard that runs my code.
>
> It is a mindless processor, churning instruction after instruction, no
> mind no standards, no nothing.
>
> I have an aesthetic view of code. What is important in it, from my
> viewpoint, is clarity of design and above all, that
> IT WORKS.
>
> Code can be written up to the best standards, but if doesn't work or if
> it doesn't perform very well I do not care. It is ugly.
>
> The code I am porting is the code of the IDE of lcc-win, and the code of
> the debugger. I started writing it around 1992.
>
> The IDE was one of the few pieces of code I salvaged from my failed
> lisp interpreter project, that was a technical success but a commercial
> failure.
>
> It has been ported to windows 16 bits (from 32 bit DOS emulator with
> Delorie), then ported to windows 32 bits in 1996 (windows 95), then
> ported to linux 32 bits , under GTK, and then to windows 64 bits.
>
> Believe me, I know what porting means, what is important in code
> what is not.
>
>>
>>> There is no simple solution. It means go over the
>>> code and put casts everywhere, fix the new bugs
>>> as you dscover them, etc.
>>>
>>> Don't feel like it. There are more interesting things to do.
>>>
>>
>>
>> If one believes in the engineering aspect of software development,
>> then maintenance is part of the deal. As pointed out elsewhere in
>> this thread, size_t has been around for 18 years so having to deal
>> with it should not exactly be a surprise.
>>
>
> Yeah. I have to cope with the possibility of strings larger than 2GB.
> Gosh!
You're making not necessarily valid assumptions regarding, int,
size_t, and the maximum size of a string that your application
may want to deal with.
>
>> That being said, you are free to either deal with updating your code
>> or to ignore the compiler warnings. It all depends on how much you
>> and those others who use the code care about it working correctly and
>> how difficult it is to port to other compilers, platforms, operating
>> systems, etc., when needed.
>>
>
> I think that the fix proposed will fit the bill.
>
>> As an example of consequences of not keeping code up to date, I've
>> spent something in excess of a week getting a network communications
>> package for a little I/O box embeded in one of our systems to compile
>> and work correctly after an OS/compiler upgrade of the system needing
>> to use the I/O box. It turns out that the latest version of the
>> software package supplied by the vender is *full* of pre C89 crud.
>
> You will agree with me that THAT is much serious than a few compiler
> warnings because of size_t I suppose...
>
> I adopted immediately C89 when it come out, because of the prototypes.
> It was an INCREDIBLE relaxing thing that I did NOT have to worry
> anymore if I always passed the right number of parameters to my
> functions. The compiler would yell at me. What a fantastic feeling.
> I still remember it!
Let me get this straight - you adopted C89 because of the prototyping,
yet when you started your project in 1992, you didn't bother to use
size_t, included in that same standard, and now you are complaining
about compiler warnings due to not using size_t?
>
>> I now have the system working again to the point that it is useful,
>> however the porting hassles serve as a disincentive for purchasing any
>> more of the company's products.
>>
>
> Sorry but did you contact the vendor? If they still exists and
> sell that package they have surely upgraded it...
>
Nope. I'm using the latest version of their software, dated August
2005.
---Craig
________________________________________________________________________
Craig A. Gullixson
Instrument Engineer INTERNET: cgullixson@nso.edu
National Solar Observatory/Sac. Peak PHONE: (505) 434-7065
Sunspot, NM 88349 USA FAX: (505) 434-7029
|
|
0
|
|
|
|
Reply
|
craig8538 (9)
|
9/4/2007 4:44:47 PM
|
|
Kelsey Bjarnason <kbjarnason@gmail.com> writes:
> [snips]
>
> On Sun, 02 Sep 2007 19:00:43 +0100, Malcolm McLean wrote:
>
>>> If I were writing such apps, I'd write the body of the code to be as
>>> conforming as possible, meaning it is effectively immune to switching to
>>> a different OS, compiler, or version of a compiler.
>>>
>> What you not uncommonly find is that the actual processing that the app
>> performs is trivial - maybe it adds a few columns of numbers together and
>> produces a report.
>
> Excuse?
>
> Right now I'm working on a chess app; virtually all the code is
> computational, with nigh-on nil for user interaction.
>
> Recently I've written reporting apps - log processing, for example - which
> read and process gigabytes of data, then produce web pages delineating
> the results. No user interaction at all.
>
> In fact, in all the coding I've ever done, the vast majority of it was
> code to actually _do_ things, which means the code for processing
> outweighs the code for interaction by a very large margin.
>
> If you constrain yourself to nothing but toy programs, you'll get a toy
> program view of the universe. We don't constrain ourselves this way; we
> actually work on programs with some meat to them.
Who is "we"? Are you talking of you and your buddies at work, or for you
and the other posters here? There are zillions of C apps, you are
probably using one now, where the processing is indeed trivial compared
to wait time.
And waiting for UI, doesn't in any way mean that the program has no
"meat on its bones". Some user driven apps are by far the most
complicated needing complex graphics, sound and process handling.
Frankly, I think you are becoming rather boring with your increasingly
superior notions about what constitutes a "real program". Report
generation programs tend to be bog standard, tedious coding
exercises. They are as "toy like" as any others you might care to
mention. In fact my first *ever* commercial apps were just that - mind
numbingly boring C coding for back office reports for huge retails
stores. Nothing big or clever in them I am afraid.
|
|
0
|
|
|
|
Reply
|
rgrdev (1814)
|
9/4/2007 4:57:39 PM
|
|
Army1987 wrote:
> On Thu, 30 Aug 2007 05:29:26 -0400, CBFalconer wrote:
>
>> jacob navia wrote:
>> ... snip ...
>>> Because that int is used in many other contexts later, for instance
>>> comparing it with other integers.
>>>
>>> int len = strlen(str);
>>>
>>> for (i=0; i<len; i++) {
>>> /// etc
>>> }
>>>
>>> The i<len comparison would provoke a warning if len is unsigned...
>> I fail to see any reason why that 'i' should not be declared as
>> unsigned. Well, maybe extreme laziness.
> Because an idiot programmer could write unsigned i;
> for (i--; i >= 0; i--) and disasters would happen.
Put me in idiot club then. :-( Here, is the code snippet of a bug I
wrote today:
size_t i, j, k;
[...]
for (i=0, k=1; i<iso->field[P1_BITMAPS].length; i++)
{
for (j=7; j>=0; j--,k++)
{
if ( (bitmap[i] >> j) & 1 )
{
has_field[k] = TRUE;
}
else
{
has_field[k] = FALSE;
}
}
}
now the code has
int i, j, k;
while "iso->field[P1_BITMAPS].length" still has size_t type.
--
Tor <torust [at] online [dot] no>
|
|
0
|
|
|
|
Reply
|
tor_rustad (506)
|
9/4/2007 6:05:41 PM
|
|
[snips]
On Tue, 04 Sep 2007 18:57:39 +0200, Richard wrote:
>>>> If I were writing such apps, I'd write the body of the code to be as
>>>> conforming as possible, meaning it is effectively immune to switching to
>>>> a different OS, compiler, or version of a compiler.
>>>>
>>> What you not uncommonly find is that the actual processing that the app
>>> performs is trivial - maybe it adds a few columns of numbers together and
>>> produces a report.
> Who is "we"?
Based on some 20 years' coding and examining the code of others, I'd say
"most programmers".
> and the other posters here? There are zillions of C apps, you are
> probably using one now, where the processing is indeed trivial compared
> to wait time.
Where did wait time come into the question? The discussion was about
processing done by the app, as contrasted to the UI for the app - not a
thing about wait times. Sorry, did I miss that in Malcolm's comments?
|
|
0
|
|
|
|
Reply
|
kbjarnason (4583)
|
9/4/2007 6:27:29 PM
|
|
"Kelsey Bjarnason" <kbjarnason@gmail.com> wrote in message
news:hlk0r4-8cc.ln1@spanky.localhost.net...
> [snips]
> Where did wait time come into the question? The discussion was about
> processing done by the app, as contrasted to the UI for the app - not a
> thing about wait times. Sorry, did I miss that in Malcolm's comments?
>
That's a slightly different issue. Run time is not unrelated to the
complexity of the code doing the processing, but it is not the same thing at
all. Code can be very hard to write yet execute in under just noticeable
time. Alternatively it can be very simple but soak up as much processing
power as you can throw at it.
However the majority of desktop apps do fairly trivial processing in both
senses. The functions are not mathematically complicated in any way, and
they don't take much time to execute. When I say "the majority" obviously
there are exceptions. A chess program that would beat Kasparov is one of
them.
--
Free games and programming goodies.
http://www.personal.leeds.ac.uk/~bgy1mm
|
|
0
|
 | | | | |