Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.c > #3072 > unrolled thread

int vs. unsigned int vs. size_t

Started bySteve Keller <keller@no.invalid>
First post2011-04-30 08:40 +0200
Last post2011-05-07 02:42 -0700
Articles 20 on this page of 28 — 16 participants

Back to article view | Back to comp.lang.c


Contents

  int vs. unsigned int vs. size_t Steve Keller <keller@no.invalid> - 2011-04-30 08:40 +0200
    Re: int vs. unsigned int vs. size_t Tim Prince <tprince@computer.org> - 2011-04-30 09:27 -0700
      Re: int vs. unsigned int vs. size_t Tim Prince <tprince@computer.org> - 2011-04-30 12:55 -0700
      Re: int vs. unsigned int vs. size_t Ian Collins <ian-news@hotmail.com> - 2011-05-01 10:34 +1200
    Re: int vs. unsigned int vs. size_t pozz <pozzugno@gmail.com> - 2011-04-30 19:33 +0200
      Re: int vs. unsigned int vs. size_t Ian Collins <ian-news@hotmail.com> - 2011-05-01 09:03 +1200
        Re: int vs. unsigned int vs. size_t Tim Prince <tprince@computer.org> - 2011-04-30 14:34 -0700
          Re: int vs. unsigned int vs. size_t Ian Collins <ian-news@hotmail.com> - 2011-05-01 10:37 +1200
    Re: int vs. unsigned int vs. size_t Datesfat Chicks <datesfat.chicks@gmail.com> - 2011-04-30 19:41 -0400
      Re: int vs. unsigned int vs. size_t Keith Thompson <kst-u@mib.org> - 2011-04-30 17:46 -0700
        Re: int vs. unsigned int vs. size_t Datesfat Chicks <datesfat.chicks@gmail.com> - 2011-05-01 21:27 -0400
    Re: int vs. unsigned int vs. size_t Malcolm McLean <malcolm.mclean5@btinternet.com> - 2011-04-30 22:23 -0700
    Re: int vs. unsigned int vs. size_t Dr Nick <3-nospam@temporary-address.org.uk> - 2011-05-01 14:16 +0100
      Re: int vs. unsigned int vs. size_t Barry Schwarz <schwarzb@dqel.com> - 2011-05-01 10:31 -0700
      Re: int vs. unsigned int vs. size_t Keith Thompson <kst-u@mib.org> - 2011-05-01 12:25 -0700
        Re: int vs. unsigned int vs. size_t James Kuyper <jameskuyper@verizon.net> - 2011-05-01 20:00 -0400
          Re: int vs. unsigned int vs. size_t Tim Rentsch <txr@alumni.caltech.edu> - 2011-05-02 10:17 -0700
        Re: int vs. unsigned int vs. size_t Dr Nick <3-nospam@temporary-address.org.uk> - 2011-05-02 08:37 +0100
    Re: int vs. unsigned int vs. size_t ImpalerCore <jadill33@gmail.com> - 2011-05-03 06:02 -0700
      Re: int vs. unsigned int vs. size_t Peter Nilsson <airia@acay.com.au> - 2011-05-03 15:55 -0700
      Re: int vs. unsigned int vs. size_t Luca Forlizzi <luca.forlizzi@gmail.com> - 2011-05-05 02:38 -0700
        Re: int vs. unsigned int vs. size_t ImpalerCore <jadill33@gmail.com> - 2011-05-05 06:37 -0700
          Re: int vs. unsigned int vs. size_t Angel <angel+news@spamcop.net> - 2011-05-05 16:10 +0000
          Re: int vs. unsigned int vs. size_t Malcolm McLean <malcolm.mclean5@btinternet.com> - 2011-05-05 09:35 -0700
            Re: int vs. unsigned int vs. size_t Keith Thompson <kst-u@mib.org> - 2011-05-05 11:22 -0700
              Re: int vs. unsigned int vs. size_t Peter Nilsson <airia@acay.com.au> - 2011-05-05 16:06 -0700
              Re: int vs. unsigned int vs. size_t Michael Press <rubrum@pacbell.net> - 2011-05-06 02:32 -0700
          Re: int vs. unsigned int vs. size_t Luca Forlizzi <luca.forlizzi@gmail.com> - 2011-05-07 02:42 -0700

Page 1 of 2  [1] 2  Next page →


#3072 — int vs. unsigned int vs. size_t

FromSteve Keller <keller@no.invalid>
Date2011-04-30 08:40 +0200
Subjectint vs. unsigned int vs. size_t
Message-ID<ipgasf$1q5b$1@adenine.netfront.net>
This is a style question.  To iterate through an array I often use
code similar to the following:

	#define ASIZE(a) (sizeof(a) / sizeof((a)[0])
	int a[] = { ... };

	void foo(void)
	{
		int i;
		for (i = 0; i < ASIZE(a); i++)
			/* do something with a[i]. */
	}

With all warnings enabled, gcc will warn about a comparison between
signed and unsigned integer types, because sizeof() yields a size_t
which is unsigned.  To eliminate that warning I could use unsigned int
or size_t for the variable i.  But IMO int feels most natural and
size_t might have unwanted overhead, if it is a large integer type and
I know that the array size will be very small (i.e. less than INT_MAX
elements).

So, what type for i do you prefer in cases like this?

--- news://freenews.netfront.net/ - complaints: news@netfront.net ---

[toc] | [next] | [standalone]


#3075

FromTim Prince <tprince@computer.org>
Date2011-04-30 09:27 -0700
Message-ID<922rjhFp47U1@mid.individual.net>
In reply to#3072
On 4/29/2011 11:40 PM, Steve Keller wrote:
> This is a style question.  To iterate through an array I often use
> code similar to the following:
>
> 	#define ASIZE(a) (sizeof(a) / sizeof((a)[0])
> 	int a[] = { ... };
>
> 	void foo(void)
> 	{
> 		int i;
> 		for (i = 0; i<  ASIZE(a); i++)
> 			/* do something with a[i]. */
> 	}
>
> With all warnings enabled, gcc will warn about a comparison between
> signed and unsigned integer types, because sizeof() yields a size_t
> which is unsigned.  To eliminate that warning I could use unsigned int
> or size_t for the variable i.  But IMO int feels most natural and
> size_t might have unwanted overhead, if it is a large integer type and
> I know that the array size will be very small (i.e. less than INT_MAX
> elements).
>
> So, what type for i do you prefer in cases like this?
>
How about defining a loop invariant for the loop test, with matching 
data type?
  		int i, ilimit=ASIZE(a);
  		for (i = 0; i<  ilimit; i++)

If your compiler performs optimizations based on countability of the for 
loop, this avoids uncertainty there too.

-- 
Tim Prince

[toc] | [prev] | [next] | [standalone]


#3078

FromTim Prince <tprince@computer.org>
Date2011-04-30 12:55 -0700
Message-ID<9237qcFjlrU1@mid.individual.net>
In reply to#3075
On 4/30/2011 10:24 AM, Stefan Ram wrote:
> Tim Prince<tprince@computer.org>  writes:
>> How about defining a loop invariant for the loop test, with matching
>> data type?
>>   		int i, ilimit=ASIZE(a);
>>   		for (i = 0; i<   ilimit; i++)
>
>    An invariant »ilimit«
>
> size_t ilimit = ASIZE(a);
>
>    can be made more readable as
>
> size_t const ilimit = ASIZE(a);
>
>    .
>
>
const yes, size_t no, the point is to avoid any implied up-casting 
inside the loop.

-- 
Tim Prince

[toc] | [prev] | [next] | [standalone]


#3081

FromIan Collins <ian-news@hotmail.com>
Date2011-05-01 10:34 +1200
Message-ID<923h40Fj03U2@mid.individual.net>
In reply to#3075
On 05/ 1/11 04:27 AM, Tim Prince wrote:
> On 4/29/2011 11:40 PM, Steve Keller wrote:
>> This is a style question.  To iterate through an array I often use
>> code similar to the following:
>>
>> 	#define ASIZE(a) (sizeof(a) / sizeof((a)[0])
>> 	int a[] = { ... };
>>
>> 	void foo(void)
>> 	{
>> 		int i;
>> 		for (i = 0; i<   ASIZE(a); i++)
>> 			/* do something with a[i]. */
>> 	}
>>
>> With all warnings enabled, gcc will warn about a comparison between
>> signed and unsigned integer types, because sizeof() yields a size_t
>> which is unsigned.  To eliminate that warning I could use unsigned int
>> or size_t for the variable i.  But IMO int feels most natural and
>> size_t might have unwanted overhead, if it is a large integer type and
>> I know that the array size will be very small (i.e. less than INT_MAX
>> elements).
>>
>> So, what type for i do you prefer in cases like this?
>>
> How about defining a loop invariant for the loop test, with matching
> data type?
>    		int i, ilimit=ASIZE(a);
>    		for (i = 0; i<   ilimit; i++)
>
> If your compiler performs optimizations based on countability of the for
> loop, this avoids uncertainty there too.

There already is one: (sizeof(a) / sizeof((a)[0]) is a compile time 
constant.

-- 
Ian Collins

[toc] | [prev] | [next] | [standalone]


#3077

Frompozz <pozzugno@gmail.com>
Date2011-04-30 19:33 +0200
Message-ID<iphh5a$o71$1@nnrp.ngi.it>
In reply to#3072
Il 30/04/2011 08:40, Steve Keller ha scritto:
> 	#define ASIZE(a) (sizeof(a) / sizeof((a)[0])
> 	int a[] = { ... };
>
> 	void foo(void)
> 	{
> 		int i;
> 		for (i = 0; i<  ASIZE(a); i++)
> 			/* do something with a[i]. */
> 	}

I'm reading "C Unleashed" book and I found in some listings the 
following code:

  	#define ASIZE(a) (sizeof(a) / sizeof((a)[0])
  	int a[] = { ... };

	void foo(void)
	{
		int i;
		for (i = 0; i <  (int) ASIZE(a); i++)
			/* do something with a[i]. */
	}

[toc] | [prev] | [next] | [standalone]


#3079

FromIan Collins <ian-news@hotmail.com>
Date2011-05-01 09:03 +1200
Message-ID<923bp1Fj03U1@mid.individual.net>
In reply to#3077
On 05/ 1/11 05:33 AM, pozz wrote:
> Il 30/04/2011 08:40, Steve Keller ha scritto:
>> 	#define ASIZE(a) (sizeof(a) / sizeof((a)[0])
>> 	int a[] = { ... };
>>
>> 	void foo(void)
>> 	{
>> 		int i;
>> 		for (i = 0; i<   ASIZE(a); i++)
>> 			/* do something with a[i]. */
>> 	}
>
> I'm reading "C Unleashed" book and I found in some listings the
> following code:
>
>    	#define ASIZE(a) (sizeof(a) / sizeof((a)[0])
>    	int a[] = { ... };
>
> 	void foo(void)
> 	{
> 		int i;
> 		for (i = 0; i<   (int) ASIZE(a); i++)
> 			/* do something with a[i]. */
> 	}

That's pretty gross.  If they are going to use an invariant of one type, 
they should use a counter of the same type and not an ugly, pointless 
and distracting cast.

-- 
Ian Collins

[toc] | [prev] | [next] | [standalone]


#3080

FromTim Prince <tprince@computer.org>
Date2011-04-30 14:34 -0700
Message-ID<923difFu7jU1@mid.individual.net>
In reply to#3079
On 4/30/2011 2:03 PM, Ian Collins wrote:
> On 05/ 1/11 05:33 AM, pozz wrote:
>> Il 30/04/2011 08:40, Steve Keller ha scritto:
>>> #define ASIZE(a) (sizeof(a) / sizeof((a)[0])
>>> int a[] = { ... };
>>>
>>> void foo(void)
>>> {
>>> int i;
>>> for (i = 0; i< ASIZE(a); i++)
>>> /* do something with a[i]. */
>>> }
>>
>> I'm reading "C Unleashed" book and I found in some listings the
>> following code:
>>
>> #define ASIZE(a) (sizeof(a) / sizeof((a)[0])
>> int a[] = { ... };
>>
>> void foo(void)
>> {
>> int i;
>> for (i = 0; i< (int) ASIZE(a); i++)
>> /* do something with a[i]. */
>> }
>
> That's pretty gross. If they are going to use an invariant of one type,
> they should use a counter of the same type and not an ugly, pointless
> and distracting cast.
>
The code evidently supported only INT_MAX sized arrays.  If there were 
any possibility of larger than that (certainly not far fetched 
nowadays), this ASIZE macro could have been asserted <= INT_MAX ahead of 
the loop.  size_t is not necessarily a good choice for a loop counter; 
the largest signed int type no larger than size_t might be useful.

-- 
Tim Prince

[toc] | [prev] | [next] | [standalone]


#3082

FromIan Collins <ian-news@hotmail.com>
Date2011-05-01 10:37 +1200
Message-ID<923h9fFj03U3@mid.individual.net>
In reply to#3080
On 05/ 1/11 09:34 AM, Tim Prince wrote:
> On 4/30/2011 2:03 PM, Ian Collins wrote:
>> On 05/ 1/11 05:33 AM, pozz wrote:
>>> Il 30/04/2011 08:40, Steve Keller ha scritto:
>>>> #define ASIZE(a) (sizeof(a) / sizeof((a)[0])
>>>> int a[] = { ... };
>>>>
>>>> void foo(void)
>>>> {
>>>> int i;
>>>> for (i = 0; i<  ASIZE(a); i++)
>>>> /* do something with a[i]. */
>>>> }
>>>
>>> I'm reading "C Unleashed" book and I found in some listings the
>>> following code:
>>>
>>> #define ASIZE(a) (sizeof(a) / sizeof((a)[0])
>>> int a[] = { ... };
>>>
>>> void foo(void)
>>> {
>>> int i;
>>> for (i = 0; i<  (int) ASIZE(a); i++)
>>> /* do something with a[i]. */
>>> }
>>
>> That's pretty gross. If they are going to use an invariant of one type,
>> they should use a counter of the same type and not an ugly, pointless
>> and distracting cast.
>>
> The code evidently supported only INT_MAX sized arrays.  If there were
> any possibility of larger than that (certainly not far fetched
> nowadays), this ASIZE macro could have been asserted<= INT_MAX ahead of
> the loop.  size_t is not necessarily a good choice for a loop counter;
> the largest signed int type no larger than size_t might be useful.

The range of the loop is 0 to the array length, which is a size_t.  So 
size_t is the natural choice.

The largest signed int type no larger than size_t will vary, so yet more 
pointless code would be required to determine what it is...

-- 
Ian Collins

[toc] | [prev] | [next] | [standalone]


#3083

FromDatesfat Chicks <datesfat.chicks@gmail.com>
Date2011-04-30 19:41 -0400
Message-ID<lb7pr61sakfkcfh6fbkrto76rvt2356t35@4ax.com>
In reply to#3072
On Sat, 30 Apr 2011 08:40:51 +0200, Steve Keller <keller@no.invalid>
wrote:

>This is a style question.  To iterate through an array I often use
>code similar to the following:
>
>	#define ASIZE(a) (sizeof(a) / sizeof((a)[0])
>	int a[] = { ... };
>
>	void foo(void)
>	{
>		int i;
>		for (i = 0; i < ASIZE(a); i++)
>			/* do something with a[i]. */
>	}
>
>With all warnings enabled, gcc will warn about a comparison between
>signed and unsigned integer types, because sizeof() yields a size_t
>which is unsigned.  To eliminate that warning I could use unsigned int
>or size_t for the variable i.  But IMO int feels most natural and
>size_t might have unwanted overhead, if it is a large integer type and
>I know that the array size will be very small (i.e. less than INT_MAX
>elements).
>
>So, what type for i do you prefer in cases like this?

You should use size_t.

Let me ask you a question ... do you want to create a piece of
software that works intermittently, based on the size of the array?

If the answer to that question is yes, please take a handgun and
remove yourself from the gene pool in the next day or two.

DFC

[toc] | [prev] | [next] | [standalone]


#3085

FromKeith Thompson <kst-u@mib.org>
Date2011-04-30 17:46 -0700
Message-ID<lny62ruu1y.fsf@nuthaus.mib.org>
In reply to#3083
Datesfat Chicks <datesfat.chicks@gmail.com> writes:
> On Sat, 30 Apr 2011 08:40:51 +0200, Steve Keller <keller@no.invalid>
> wrote:
[...]
>>So, what type for i do you prefer in cases like this?
>
> You should use size_t.
>
> Let me ask you a question ... do you want to create a piece of
> software that works intermittently, based on the size of the array?
>
> If the answer to that question is yes, please take a handgun and
> remove yourself from the gene pool in the next day or two.

That was uncalled for.

-- 
Keith Thompson (The_Other_Keith) kst-u@mib.org  <http://www.ghoti.net/~kst>
Nokia
"We must do something.  This is something.  Therefore, we must do this."
    -- Antony Jay and Jonathan Lynn, "Yes Minister"

[toc] | [prev] | [next] | [standalone]


#3116

FromDatesfat Chicks <datesfat.chicks@gmail.com>
Date2011-05-01 21:27 -0400
Message-ID<o22sr699tn5mdt9i55thi442fivv24hdic@4ax.com>
In reply to#3085
On Sat, 30 Apr 2011 17:46:17 -0700, Keith Thompson <kst-u@mib.org>
wrote:

>Datesfat Chicks <datesfat.chicks@gmail.com> writes:
>> On Sat, 30 Apr 2011 08:40:51 +0200, Steve Keller <keller@no.invalid>
>> wrote:
>[...]
>>>So, what type for i do you prefer in cases like this?
>>
>> You should use size_t.
>>
>> Let me ask you a question ... do you want to create a piece of
>> software that works intermittently, based on the size of the array?
>>
>> If the answer to that question is yes, please take a handgun and
>> remove yourself from the gene pool in the next day or two.
>
>That was uncalled for.

Yes, your lack of a flexible sense of humor was indeed uncalled for.

DFC

[toc] | [prev] | [next] | [standalone]


#3089

FromMalcolm McLean <malcolm.mclean5@btinternet.com>
Date2011-04-30 22:23 -0700
Message-ID<e9fb3161-a3da-4538-b378-d6fd01b9d974@e21g2000yqe.googlegroups.com>
In reply to#3072
On Apr 30, 9:40 am, Steve Keller <kel...@no.invalid> wrote:
>
> With all warnings enabled, gcc will warn about a comparison between
> signed and unsigned integer types, because sizeof() yields a size_t
> which is unsigned.  To eliminate that warning I could use unsigned int
> or size_t for the variable i.  But IMO int feels most natural and
> size_t might have unwanted overhead, if it is a large integer type and
> I know that the array size will be very small (i.e. less than INT_MAX
> elements).
>
This bis precisely the problem. Almost all integers end up being used
as an index eventually (even chars, if you think about it). Which
means that size_t gradually spreads through the code, poisoning
everything. But no-one wants to use a language where the default
integer type is called "size_t" and is unsigned.
My solution is to say that the natural integer type is the maximum
size of a memory object, and should be int. There's a minor problem
when pointers are 32 bits and arrays cover over half of memory, but
it's very rare to want an array like that.

[toc] | [prev] | [next] | [standalone]


#3102

FromDr Nick <3-nospam@temporary-address.org.uk>
Date2011-05-01 14:16 +0100
Message-ID<87tydev9vx.fsf@temporary-address.org.uk>
In reply to#3072
Steve Keller <keller@no.invalid> writes:

> This is a style question.  To iterate through an array I often use
> code similar to the following:
>
> 	#define ASIZE(a) (sizeof(a) / sizeof((a)[0])
> 	int a[] = { ... };
>
> 	void foo(void)
> 	{
> 		int i;
> 		for (i = 0; i < ASIZE(a); i++)
> 			/* do something with a[i]. */
> 	}
>
> With all warnings enabled, gcc will warn about a comparison between
> signed and unsigned integer types, because sizeof() yields a size_t
> which is unsigned.  To eliminate that warning I could use unsigned int
> or size_t for the variable i.  But IMO int feels most natural and
> size_t might have unwanted overhead, if it is a large integer type and
> I know that the array size will be very small (i.e. less than INT_MAX
> elements).
>
> So, what type for i do you prefer in cases like this?

I hit another issue with this a couple of days ago.  If you /do/ use an
unsigned type for 'i', and the array has no items in it, and you use GCC
with -W you get:
warning: comparison is always false due to limited range of data type

With a cast of the result of the sizeof division, and a normal signed
int, you get no warnings. 

I have to confess that this confuses me.
-- 
Online waterways route planner            | http://canalplan.eu
Plan trips, see photos, check facilities  | http://canalplan.org.uk

[toc] | [prev] | [next] | [standalone]


#3108

FromBarry Schwarz <schwarzb@dqel.com>
Date2011-05-01 10:31 -0700
Message-ID<tl5rr65purjjnju3kqfrgthsdsjrqqc2f8@4ax.com>
In reply to#3102
On Sun, 01 May 2011 14:16:34 +0100, Dr Nick
<3-nospam@temporary-address.org.uk> wrote:

>Steve Keller <keller@no.invalid> writes:
>
>> This is a style question.  To iterate through an array I often use
>> code similar to the following:
>>
>> 	#define ASIZE(a) (sizeof(a) / sizeof((a)[0])
>> 	int a[] = { ... };
>>
>> 	void foo(void)
>> 	{
>> 		int i;
>> 		for (i = 0; i < ASIZE(a); i++)
>> 			/* do something with a[i]. */
>> 	}
>>
>> With all warnings enabled, gcc will warn about a comparison between
>> signed and unsigned integer types, because sizeof() yields a size_t
>> which is unsigned.  To eliminate that warning I could use unsigned int
>> or size_t for the variable i.  But IMO int feels most natural and
>> size_t might have unwanted overhead, if it is a large integer type and
>> I know that the array size will be very small (i.e. less than INT_MAX
>> elements).
>>
>> So, what type for i do you prefer in cases like this?
>
>I hit another issue with this a couple of days ago.  If you /do/ use an
>unsigned type for 'i', and the array has no items in it, and you use GCC
>with -W you get:
>warning: comparison is always false due to limited range of data type
>
>With a cast of the result of the sizeof division, and a normal signed
>int, you get no warnings. 
>
>I have to confess that this confuses me.

If i is unsigned and the right operand of the < operator is known to
the compiler to be 0, then it is not possible for the expression 
    i < 0
to be true.  Hence the (overzealous?) warning.

If i is signed, the expression could be true, even if it never is.
Hence no warning.

-- 
Remove del for email

[toc] | [prev] | [next] | [standalone]


#3109

FromKeith Thompson <kst-u@mib.org>
Date2011-05-01 12:25 -0700
Message-ID<lntydeuss8.fsf@nuthaus.mib.org>
In reply to#3102
Dr Nick <3-nospam@temporary-address.org.uk> writes:
> Steve Keller <keller@no.invalid> writes:
>> This is a style question.  To iterate through an array I often use
>> code similar to the following:
>>
>> 	#define ASIZE(a) (sizeof(a) / sizeof((a)[0])
>> 	int a[] = { ... };
>>
>> 	void foo(void)
>> 	{
>> 		int i;
>> 		for (i = 0; i < ASIZE(a); i++)
>> 			/* do something with a[i]. */
>> 	}
>>
>> With all warnings enabled, gcc will warn about a comparison between
>> signed and unsigned integer types, because sizeof() yields a size_t
>> which is unsigned.  To eliminate that warning I could use unsigned int
>> or size_t for the variable i.  But IMO int feels most natural and
>> size_t might have unwanted overhead, if it is a large integer type and
>> I know that the array size will be very small (i.e. less than INT_MAX
>> elements).
>>
>> So, what type for i do you prefer in cases like this?
>
> I hit another issue with this a couple of days ago.  If you /do/ use an
> unsigned type for 'i', and the array has no items in it, and you use GCC
> with -W you get:
> warning: comparison is always false due to limited range of data type

How could the array have no items in it?  C doesn't have zero-sized
arrays.

> With a cast of the result of the sizeof division, and a normal signed
> int, you get no warnings. 
>
> I have to confess that this confuses me.

-- 
Keith Thompson (The_Other_Keith) kst-u@mib.org  <http://www.ghoti.net/~kst>
Nokia
"We must do something.  This is something.  Therefore, we must do this."
    -- Antony Jay and Jonathan Lynn, "Yes Minister"

[toc] | [prev] | [next] | [standalone]


#3113

FromJames Kuyper <jameskuyper@verizon.net>
Date2011-05-01 20:00 -0400
Message-ID<ipks6g$b43$1@dont-email.me>
In reply to#3109
On 05/01/2011 03:25 PM, Keith Thompson wrote:
...
> How could the array have no items in it?  C doesn't have zero-sized
> arrays.

An array can't have 0 elements; but an array with 1024 elements might
have none of them filled in yet, in which case it doesn't have any items.


-- 
James Kuyper

[toc] | [prev] | [next] | [standalone]


#3132

FromTim Rentsch <txr@alumni.caltech.edu>
Date2011-05-02 10:17 -0700
Message-ID<kfn1v0hxbrc.fsf@x-alumni2.alumni.caltech.edu>
In reply to#3113
James Kuyper <jameskuyper@verizon.net> writes:

> On 05/01/2011 03:25 PM, Keith Thompson wrote:
> ...
>> How could the array have no items in it?  C doesn't have zero-sized
>> arrays.
>
> An array can't have 0 elements; but an array with 1024 elements might
> have none of them filled in yet, in which case it doesn't have any items.

One presumes the expression being compared against in
such a case would not be a compile-time constant,
and so would not produce a warning message for the
comparison always being false.

[toc] | [prev] | [next] | [standalone]


#3122

FromDr Nick <3-nospam@temporary-address.org.uk>
Date2011-05-02 08:37 +0100
Message-ID<87mxj5v9gr.fsf@temporary-address.org.uk>
In reply to#3109
Keith Thompson <kst-u@mib.org> writes:

> Dr Nick <3-nospam@temporary-address.org.uk> writes:
>> Steve Keller <keller@no.invalid> writes:
>>> This is a style question.  To iterate through an array I often use
>>> code similar to the following:
>>>
>>> 	#define ASIZE(a) (sizeof(a) / sizeof((a)[0])
>>> 	int a[] = { ... };
>>>
>>> 	void foo(void)
>>> 	{
>>> 		int i;
>>> 		for (i = 0; i < ASIZE(a); i++)
>>> 			/* do something with a[i]. */
>>> 	}
>>>
>>> With all warnings enabled, gcc will warn about a comparison between
>>> signed and unsigned integer types, because sizeof() yields a size_t
>>> which is unsigned.  To eliminate that warning I could use unsigned int
>>> or size_t for the variable i.  But IMO int feels most natural and
>>> size_t might have unwanted overhead, if it is a large integer type and
>>> I know that the array size will be very small (i.e. less than INT_MAX
>>> elements).
>>>
>>> So, what type for i do you prefer in cases like this?
>>
>> I hit another issue with this a couple of days ago.  If you /do/ use an
>> unsigned type for 'i', and the array has no items in it, and you use GCC
>> with -W you get:
>> warning: comparison is always false due to limited range of data type
>
> How could the array have no items in it?  C doesn't have zero-sized
> arrays.

I did wonder about that, I presume it's (another) GNU extension.

I didn't intend the array to have no elements in it.  It was being used
like this:

extern void Populate_Autoconf_Variable(value *val) {
  unsigned int i;
  char* wk[][2] = {
#include "processed_config_h"
  };
  for(i=0; i<sizeof wk/sizeof wk[1]); i++) {
    Set_Lookup_String(val,wk[i][0],wk[i][1]);
  }
}

where processed_config_h should be a list of items like this:
{"HAVE_FLOCK","1"},
{"HAVE_GD","1"},
{"HAVE_GNUPLOT","1"},
{"HAVE_INTTYPES_H","1"},
{"HAVE_LIBDL","1"},

so it allows the scripting language to have access to the details of the
configuration it was built under.  But the code to generate
processed_config_h was failing and creating an empty file.

The result was the previously mentioned error at the for, not anything
at the array definition.

Oh, and all praise to the C committee for allowing that final trailing
comma, it does make life a lot easier.
-- 
Online waterways route planner            | http://canalplan.eu
Plan trips, see photos, check facilities  | http://canalplan.org.uk

[toc] | [prev] | [next] | [standalone]


#3173

FromImpalerCore <jadill33@gmail.com>
Date2011-05-03 06:02 -0700
Message-ID<30a180f5-bc96-44b2-8921-bb135d9b38be@v10g2000yqn.googlegroups.com>
In reply to#3072
On Apr 30, 2:40 am, Steve Keller <kel...@no.invalid> wrote:
> This is a style question.  To iterate through an array I often use
> code similar to the following:
>
>         #define ASIZE(a) (sizeof(a) / sizeof((a)[0])
>         int a[] = { ... };
>
>         void foo(void)
>         {
>                 int i;
>                 for (i = 0; i < ASIZE(a); i++)
>                         /* do something with a[i]. */
>         }
>
> With all warnings enabled, gcc will warn about a comparison between
> signed and unsigned integer types, because sizeof() yields a size_t
> which is unsigned.  To eliminate that warning I could use unsigned int
> or size_t for the variable i.  But IMO int feels most natural and
> size_t might have unwanted overhead, if it is a large integer type and
> I know that the array size will be very small (i.e. less than INT_MAX
> elements).
>
> So, what type for i do you prefer in cases like this?

Often the initial reason to use int instead of size_t stems from
wanting to loop backwards and use a negative value to terminate the
loop.

for ( i = N-1; i >= 0; --i )

For people learning to write these kinds of loops where 'i' is
unsigned and have been bitten by their mistake, the first inclination
is to just use a signed type, and cast any unsigned value to the
signed type within the loop, which may eventually lead them to using
int for every index type.  The 'int' type is also the predominant
index type in teaching materials as it avoids the caveats of using
unsigned indexes (and less typing), reinforcing the perception that
integer indexes are standard or best practice.

Then people start telling you that casting is ugly, required because
you are using a signed index with the useful construct
'sizeof(array) / sizeof(array[0])'.  So to compensate, the you venture
into the realm of unsigned indexes to avoid the cast, and you write:

for ( i = N; i > 0; --i )
  do_something_with_index[i-1];

But now your loop is stuck with 'i-1', as sometimes you'll forget it
and access 'array[i=N]' by mistake and flub something up, or your brow
starts to twitch at the inefficiency of 'i-1' and you seek medical
help.

Then you go on usenet, and C gurus from far away places will present
you with a 'size_t' loop free from those constraints.  You will think
it's really cool and start using it, until your friends unfamiliar
with the idiom see it, try to recreate it, and flub it up because they
don't know the idiom.  It's discovery is hidden far away in dusty
archives only ventured by adventurous wizards who enjoy searching for
secrets of the arcane.  You may decide to keep the secret from less
capable wizards lest they should injure themselves and others by
attempting the incantation unprepared or you'll have to clean up their
logic bombs afterwards.

Eventually one may venture into using an signed index type that
assigns negative values as the 'not found' semantic, typically as the
result of a search into an array or other container.  Or one may
possibly want to have two indexes into an array, and desire to
subtract them without dealing with underflow.

Are you ready to play Let's Make a Deal?

Behind door number 1, you have int, with its familiarity, resilience
to underflow logic errors, and some annoying cast graffiti that will
earn you the disdain of the upper echelon.

Door number 2, you have the size_t index type with its familiar
looping structure, no casts, and a potentially annoying [i-1] in your
loop.

Or door number 3, with a size_t index with less familiar idiomatic
loop, no casts, and bragging rights on how clever you are.

As far as my personal preferences, I prefer using 'size_t' loops for
simple 'for' loops that increment up like the one in your post.
However, I tend to use 'u' instead of 'i' as the generic index name
(with 'v', 'w' instead of 'j' and 'k') simply as a reminder that the
index is unsigned.  If the loop iterates backwards using an index and
a negative terminating value, I still prefer using a signed type (and
live with the cast graffiti) for my own personal readability's sake.
If the index represents a position in an array, but uses a negative
value to indicate 'not found', I use 'ssize_t', which I have to define
myself to a type the same size as 'size_t' but signed, typically
'ptrdiff_t'.  If there is subtraction involved with loop indices that
has a range that extends into negative values, I use signed types.

Best regards,
John D.

[toc] | [prev] | [next] | [standalone]


#3205

FromPeter Nilsson <airia@acay.com.au>
Date2011-05-03 15:55 -0700
Message-ID<6ac250e7-6e7b-4999-930c-77c8522ab575@d26g2000prn.googlegroups.com>
In reply to#3173
ImpalerCore <jadil...@gmail.com> wrote:
> ...
> Often the initial reason to use int instead of size_t stems
> from wanting to loop backwards and use a negative value to
> terminate the loop.
>
> for ( i = N-1; i >= 0; --i )

  size_t i;
  for (i = N; i-- > 0; )
    ...a[i]...

I've seen people stylise it to...

  for (i = N; i --> 0; )

--
Peter

[toc] | [prev] | [next] | [standalone]


Page 1 of 2  [1] 2  Next page →

Back to top | Article view | comp.lang.c


csiph-web