Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C Programming > Please help optimize (and standarize) this code...

Reply
Thread Tools

Please help optimize (and standarize) this code...

 
 
Mark F. Haigh
Guest
Posts: n/a
 
      03-13-2005
gtippery wrote:
<snip>
>
> > 3. What's the biggest number of elements that your array can have?
> > Check your platform docs. It may be more than int can handle, but

> less
> > than or equal to what size_t can handle.
> >

>
> The platform limit is 64KB for any one item (i8086). The array would
> be the limiting factor in this case (at something over 5,000

elements),

[OT]

The limits change depending on the compiler / memory model combination.
I know there's one out there (a huge model variant) using 16 bit int
and 32 bit size_t. Can't remember which compiler, and don't care to--
hopefully my DOS programming days are far behind me (pun intended),
never to return.

<snip>
>
> If size_t isn't actually an int (of some standard type), isn't that
> going to be a problem in the for()? I thought the index variable had
> to be an integer or enumeration.
>


The standard states (7.17) that "size_t [...] is the unsigned integer
type of the result of the sizeof operator". Use it like any other
integral type, including in for statements and subscripting operators
(ie []). Generally, size_t is a better choice than int for array
subscripting.

So, making a few simple modifications to my previously posted code:

---snip---
#include <stdio.h>

#define MAXCOL 2
#define NAMLEN 8
#define EXTLEN 3

struct NameExt
{
char name[NAMLEN];
char ext[EXTLEN];
};


int main(void)
{
/* Some sample filenames */
struct NameExt list[] = {
{ "One ", "1 " },
{ "TwoTwo ", "22 " },
{ "ThreeThr", "333" },
{ "Four ", "4 " },
{ "FiveFive", "55 " },
{ "SixSixSi", "666" },
};

/* Print the array out */
size_t i;
for(i = 0; i < sizeof(list) / sizeof(list[0]); i++)
printf("%-*.*s.%-*.*s%s",
NAMLEN, NAMLEN, list[i].name,
EXTLEN, EXTLEN, list[i].ext,
(i + 1) % MAXCOL ? " " : "\n");

return 0;
}
--- snip ---

[mark@icepick ~]$ gcc -Wall -O2 -ansi -pedantic foo.c -o foo
[mark@icepick ~]$ ./foo
One .1 TwoTwo .22
ThreeThr.333 Four .4
FiveFive.55 SixSixSi.666

I believe that's what you're looking for. That's the simplest code I
can think of off the top of my head.


Mark F. Haigh
http://www.velocityreviews.com/forums/(E-Mail Removed)

 
Reply With Quote
 
 
 
 
gtippery
Guest
Posts: n/a
 
      03-13-2005
Mark F. Haigh wrote:
> gtippery wrote:
> <snip>
> >
> > If size_t isn't actually an int (of some standard type), isn't that
> > going to be a problem in the for()? I thought the index variable

had
> > to be an integer or enumeration.
> >

>
> The standard states (7.17) that "size_t [...] is the unsigned integer
> type of the result of the sizeof operator". Use it like any other
> integral type, including in for statements and subscripting operators
> (ie []). Generally, size_t is a better choice than int for array
> subscripting.


I still don't understand why it's "better", by which I suppose you mean
"bigger" (meaning wider range - for positive values, of course).
Wouldn't an implementation with e.g. 16-bit size_t and 32-bit type int
meet the spec you quote? Do you mean it's _likely_ to be bigger? Or
do you just mean that for a given size, unsigned int is (probably)
"bigger" than signed int?

Or maybe I've missed the point. Other than range, is there some reason
specific to array subscripting to prefer size_t ?

>
> So, making a few simple modifications to my previously posted code:
>
> ---snip---
> #include <stdio.h>
>
> #define MAXCOL 2
> #define NAMLEN 8
> #define EXTLEN 3
>
> struct NameExt
> {
> char name[NAMLEN];
> char ext[EXTLEN];
> };
>
>
> int main(void)
> {
> /* Some sample filenames */
> struct NameExt list[] = {
> { "One ", "1 " },
> { "TwoTwo ", "22 " },
> { "ThreeThr", "333" },
> { "Four ", "4 " },
> { "FiveFive", "55 " },
> { "SixSixSi", "666" },
> };
>
> /* Print the array out */
> size_t i;
> for(i = 0; i < sizeof(list) / sizeof(list[0]); i++)
> printf("%-*.*s.%-*.*s%s",
> NAMLEN, NAMLEN, list[i].name,
> EXTLEN, EXTLEN, list[i].ext,
> (i + 1) % MAXCOL ? " " : "\n");
>
> return 0;
> }
> --- snip ---
>
> [mark@icepick ~]$ gcc -Wall -O2 -ansi -pedantic foo.c -o foo
> [mark@icepick ~]$ ./foo
> One .1 TwoTwo .22
> ThreeThr.333 Four .4
> FiveFive.55 SixSixSi.666
>
> I believe that's what you're looking for. That's the simplest code I
> can think of off the top of my head.
>
>
> Mark F. Haigh
> (E-Mail Removed)


That is indeed the desired output format, and indeed simple. With
luck, the compiler will factor out the constant expression in the for's
test expression.

I note you've changed the internal data representation somewhat, but I
assume it was just to simplify the example by using preinitialization.
I wanted to do that for the initial posting, but couldn't figure out
how. Is that an array of structures of strings? (As I mentioned, I
have trouble with C's declaration syntax, but I'm learning -- I hope.)

 
Reply With Quote
 
 
 
 
Michael Mair
Guest
Posts: n/a
 
      03-13-2005
gtippery wrote:
> Mark F. Haigh wrote:
>
>>gtippery wrote:
>><snip>
>>
>>>If size_t isn't actually an int (of some standard type), isn't that
>>>going to be a problem in the for()? I thought the index variable

>
> had
>
>>>to be an integer or enumeration.
>>>

>>
>>The standard states (7.17) that "size_t [...] is the unsigned integer
>>type of the result of the sizeof operator". Use it like any other
>>integral type, including in for statements and subscripting operators
>>(ie []). Generally, size_t is a better choice than int for array
>>subscripting.

>
> I still don't understand why it's "better", by which I suppose you mean
> "bigger" (meaning wider range - for positive values, of course).
> Wouldn't an implementation with e.g. 16-bit size_t and 32-bit type int
> meet the spec you quote? Do you mean it's _likely_ to be bigger? Or
> do you just mean that for a given size, unsigned int is (probably)
> "bigger" than signed int?
>
> Or maybe I've missed the point. Other than range, is there some reason
> specific to array subscripting to prefer size_t ?


size_t is the type of the result of the sizeof operator and the
type of argument taken by the dynamic memory allocation routines
malloc/calloc/realloc -- so, basically, every object you work with
has a size in bytes which can be expressed in size_t. The same
guarantee does not hold for short, int, long of either signed or
unsigned variety. So, using size_t for your index variables, you
can _never_ (*) go wrong. The downside is that you have to be
more careful with your loop tests as unsigned integer types never
can provide values <0.

(*) never: There are no absolutes. Using automatic or static
or dynamically allocated storage, within standard C you will be
on the safe side. Note that size_t has not to be large enough
to count, for example, the number of bytes in a file.

[snip: solved problem]


Cheers
Michael
--
E-Mail: Mine is an /at/ gmx /dot/ de address.
 
Reply With Quote
 
Mark F. Haigh
Guest
Posts: n/a
 
      03-13-2005
gtippery wrote:
<large snip>
>
> I still don't understand why it's "better", by which I suppose you

mean
> "bigger" (meaning wider range - for positive values, of course).
> Wouldn't an implementation with e.g. 16-bit size_t and 32-bit type

int
> meet the spec you quote? Do you mean it's _likely_ to be bigger? Or
> do you just mean that for a given size, unsigned int is (probably)
> "bigger" than signed int?
>
> Or maybe I've missed the point. Other than range, is there some

reason
> specific to array subscripting to prefer size_t ?


When you're talking about the *size* of things, use size_t. Take the
canonical example (incidentially, on a DOS-like platform):

#define SIZE 20000
char buf[SIZE];

Let's say it was changed to:

#define SIZE 40000

The thing is, any loop using a signed int (16 bit) index will fail
after element 32767, causing undefined behavior (signed integer
overflow). A size_t would make it to the maximum *size* buf can be.
The size of int is really unrelated to the maximum size of objects.

<large snip>
>
> That is indeed the desired output format, and indeed simple. With
> luck, the compiler will factor out the constant expression in the

for's
> test expression.
>
> I note you've changed the internal data representation somewhat, but

I
> assume it was just to simplify the example by using

preinitialization.
> I wanted to do that for the initial posting, but couldn't figure out
> how. Is that an array of structures of strings? (As I mentioned, I
> have trouble with C's declaration syntax, but I'm learning -- I

hope.)

The internal data representation is the same as you need. C does not
include the terminating null ('\0') if there is no room for it:

6.7.8 Initialization

[...]

[#14] An array of character type may be initialized by a
character string literal, optionally enclosed in braces.
Successive characters of the character string literal
(including the terminating null character if there is room
or if the array is of unknown size) initialize the elements
of the array.

Since the size of each array is specified in each case (8 and 3,
respectively), if you provide exactly 8 and exactly 3 characters for
each initializer, the \0 will not be tacked on to the end. In other
words, the C implementation will not overflow the buffer for you, it'll
leave you to do that on your own.

Keep it up. We like the hard questions around here.


Mark F. Haigh
(E-Mail Removed)

 
Reply With Quote
 
pete
Guest
Posts: n/a
 
      03-13-2005
Michael Mair wrote:

> size_t is the type of the result of the sizeof operator and the
> type of argument taken by the dynamic memory allocation routines
> malloc/calloc/realloc -- so, basically, every object you work with
> has a size in bytes which can be expressed in size_t. The same
> guarantee does not hold for short, int, long of either signed or
> unsigned variety.


The same guarantee has to hold for the highest ranking
unsigned type, which is unsigned long in C89.
size_t has the option of being smaller than the highest ranking
unsigned type, for implementations where that may be desirable.
 
Reply With Quote
 
gtippery
Guest
Posts: n/a
 
      03-13-2005

Michael Mair wrote:
....
> Note that size_t has not to be large enough
> to count, for example, the number of bytes in a file.
>


"has not to be"? Ah, was that idiom for "does not have to be", or typo
for "has got to be"?

 
Reply With Quote
 
gtippery
Guest
Posts: n/a
 
      03-13-2005
pete wrote:
> Michael Mair wrote:
>
> > size_t is the type of the result of the sizeof operator and the
> > type of argument taken by the dynamic memory allocation routines
> > malloc/calloc/realloc -- so, basically, every object you work with
> > has a size in bytes which can be expressed in size_t. The same
> > guarantee does not hold for short, int, long of either signed or
> > unsigned variety.

>
> The same guarantee has to hold for the highest ranking
> unsigned type, which is unsigned long in C89.
> size_t has the option of being smaller than the highest ranking
> unsigned type, for implementations where that may be desirable.


I'm thinking perhaps a segmented or paged architecture. Wider
operands, but paged addressing using fewer address bits. Seems to me a
number of older computers were like this, as well as some present-day
microcontrollers (i8051?)

And some nominally 32-bit machines have a wider integer type supported
by their FPU. You can calculate with it, but you can't address with
it.

 
Reply With Quote
 
gtippery
Guest
Posts: n/a
 
      03-13-2005

Mark F. Haigh wrote:

....

> The internal data representation is the same as you need. C does not
> include the terminating null ('\0') if there is no room for it:
>
> 6.7.8 Initialization
>
> [...]
>
> [#14] An array of character type may be initialized by a
> character string literal, optionally enclosed in braces.
> Successive characters of the character string literal
> (including the terminating null character if there is room
> or if the array is of unknown size) initialize the elements
> of the array.
>
> Since the size of each array is specified in each case (8 and 3,
> respectively), if you provide exactly 8 and exactly 3 characters for
> each initializer, the \0 will not be tacked on to the end. In other
> words, the C implementation will not overflow the buffer for you,

it'll
> leave you to do that on your own.
>


That's handy. What happens if you initialize a char[8] with
"123456789"? I mean, I can check what "happens" for me, but what's
_supposed_ to happen?

> Keep it up. We like the hard questions around here.
>


That's _definitely_ a Good Thing <grin>.

 
Reply With Quote
 
Michael Mair
Guest
Posts: n/a
 
      03-13-2005
gtippery wrote:
> Michael Mair wrote:
> ...
>
>> Note that size_t has not to be large enough
>>to count, for example, the number of bytes in a file.

>
> "has not to be"? Ah, was that idiom for "does not have to be", or typo
> for "has got to be"?


The former

Cheers
Michael
--
E-Mail: Mine is an /at/ gmx /dot/ de address.
 
Reply With Quote
 
Michael Mair
Guest
Posts: n/a
 
      03-13-2005
pete wrote:
> Michael Mair wrote:
>
>
>>size_t is the type of the result of the sizeof operator and the
>>type of argument taken by the dynamic memory allocation routines
>>malloc/calloc/realloc -- so, basically, every object you work with
>>has a size in bytes which can be expressed in size_t. The same
>>guarantee does not hold for short, int, long of either signed or
>>unsigned variety.

>
> The same guarantee has to hold for the highest ranking
> unsigned type, which is unsigned long in C89.
> size_t has the option of being smaller than the highest ranking
> unsigned type, for implementations where that may be desirable.


Thanks for the expansion -- I thought I'd better leave that
out as we then get to C89 vs. C99.
size_t does always fit.

-Michael
--
E-Mail: Mine is an /at/ gmx /dot/ de address.
 
Reply With Quote
 
 
 
Reply

Thread Tools

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

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


Similar Threads
Thread Thread Starter Forum Replies Last Post
please help optimize sub QoS@domain.invalid Perl Misc 16 10-20-2007 11:50 AM
Please Help me Optimize my Code TF ASP .Net 10 06-28-2007 06:46 AM
scipy.optimize.lbfgsb help please!!! mclaugb Python 4 01-21-2007 12:36 AM
Optimize this please? Daniel T. C++ 13 11-29-2006 08:11 PM
please help... ...me learn C++ please please please :) KK C++ 2 10-14-2003 02:08 PM



Advertisments