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

portable ascii-hex conversion

P: n/a
All,

I have a series of characters which I need to convert to integer values.
Each character is read in turn from a function 'nextch', and hex-digits are
identified by the isxdigit function - so I'm looking at '0' - '9', 'A' - 'Z'
and 'a' - 'z'.

Here is what I've got:

int num = 0;
int ch = nextch(); /* nextc obtains the next character value */

while(isxdigit(ch))
{
if(isdigit(ch))
ch = ch - '0'; /* this is portable I believe */
else
ch = (ch & ~0x20) - 'A' + 10; /* not sure if this is ok */

num = num * 0x10 + ch;
ch = nextch();
}

If you look at the if-else statement inside the while() loop, you will see
how I attempt to convert 'ch' from a character-value to a numeric value in
the range 0-15 inclusive. But I have doubts about the ((ch & ~0x20) - 'A' +
10) expression:

It assumes that 'A' - 'F' are consecutive values
It assumes that 'a' - 'f' are consecutive, and are always 0x20 above their
'uppercase' counterparts.

Are these assumptions correct? I'm guessing the code is non-portable, so
does anyone have a neat(er) suggestion?

p.s. I derived this code from the lcc compiler sourcecode...

James
Nov 8 '06 #1
Share this Question
Share on Google+
28 Replies


P: n/a
In article <lt********************@pipex.net>,
James Brown <no*@home.netwrote:
>I have a series of characters which I need to convert to integer values.
Each character is read in turn from a function 'nextch', and hex-digits are
identified by the isxdigit function - so I'm looking at '0' - '9', 'A' - 'Z'
and 'a' - 'z'.
>Here is what I've got:
>int num = 0;
int ch = nextch(); /* nextc obtains the next character value */
>while(isxdigit(ch))
What if it was EOF ?
>{
if(isdigit(ch))
ch = ch - '0'; /* this is portable I believe */
Yes.
else
ch = (ch & ~0x20) - 'A' + 10; /* not sure if this is ok */
The & ~0x20 is a hidden toupper() and not portable to non-ASCII.

And as you had thought, 'A' through 'F' are not guaranteed to be
consequative or even increasing order.

num = num * 0x10 + ch;
What if you overflow your int ?
ch = nextch();
}
>Are these assumptions correct? I'm guessing the code is non-portable, so
does anyone have a neat(er) suggestion?
fetch more ch as long as isxdigit(ch) and you haven't gotten
more chars than you can handle, and store them into a buffer.
Then strtoul() specifying base 16.

If you have particular reasons for handling the characters yourself,
then create a translation table of size UCHAR_MAX,
and initialize it, tr['0'+i] = i for i from 0 to 9, and
tr['A'] = 10, tr['B'] = 11, etc., tr['a'] = 10, tr['b'] = 11, etc.,
then to do the conversion, just determine isxdigit(ch) and if so
then the converted value is tr[ch]. Yes, this has the potential
to waste UCHAR_MAX - 26 slots, but it is also a portable single-step
conversion with no math (other than normal array indexing)
--
Programming is what happens while you're busy making other plans.
Nov 8 '06 #2

P: n/a
"Walter Roberson" <ro******@ibd.nrc-cnrc.gc.cawrote in message
news:ei**********@canopus.cc.umanitoba.ca...
In article <lt********************@pipex.net>,
James Brown <no*@home.netwrote:
>>I have a series of characters which I need to convert to integer values.
Each character is read in turn from a function 'nextch', and hex-digits
are
identified by the isxdigit function - so I'm looking at '0' - '9', 'A' -
'Z'
and 'a' - 'z'.
>>Here is what I've got:
>>int num = 0;
int ch = nextch(); /* nextc obtains the next character value */
>>while(isxdigit(ch))

What if it was EOF ?
I thought it would be ok? ch would be EOF, which would cause isxdigit to
return(0), and the loop would break out. Is this not what would happen?
>
>>{
if(isdigit(ch))
ch = ch - '0'; /* this is portable I believe */

Yes.
> else
ch = (ch & ~0x20) - 'A' + 10; /* not sure if this is ok */

The & ~0x20 is a hidden toupper() and not portable to non-ASCII.

And as you had thought, 'A' through 'F' are not guaranteed to be
consequative or even increasing order.

> num = num * 0x10 + ch;

What if you overflow your int ?
yes, I hadn't gotten as far as checking for overflow, that's my next task.
>
> ch = nextch();
}
>>Are these assumptions correct? I'm guessing the code is non-portable, so
does anyone have a neat(er) suggestion?

fetch more ch as long as isxdigit(ch) and you haven't gotten
more chars than you can handle, and store them into a buffer.
Then strtoul() specifying base 16.
Definitely a nice solution, but I think it will be hard to detect overflows?
My compiler documentation for strtoul says that it returns ULONG_MAX on
overflow, but how do I distinguish this from the case when I encounter the
actual ULONG_MAX value? This is why I am hand-coding this thing, so that I
can emit appropriate warning messages when such things happen.
>
If you have particular reasons for handling the characters yourself,
then create a translation table of size UCHAR_MAX,
and initialize it, tr['0'+i] = i for i from 0 to 9, and
tr['A'] = 10, tr['B'] = 11, etc., tr['a'] = 10, tr['b'] = 11, etc.,
then to do the conversion, just determine isxdigit(ch) and if so
then the converted value is tr[ch]. Yes, this has the potential
to waste UCHAR_MAX - 26 slots, but it is also a portable single-step
conversion with no math (other than normal array indexing)
--
Programming is what happens while you're busy making other plans.
I'll definitely consider this as a solution - I was hoping for a 1/2 liner
(calling a c-runtime func would be ideal), but it looks like a lookup table
may be the most appropriate way forward. I'm not too concerned with
performance though - I would prefer a simple loop above all else.

thanks,
James


Nov 8 '06 #3

P: n/a
>>
>> num = num * 0x10 + ch;

What if you overflow your int ?

yes, I hadn't gotten as far as checking for overflow, that's my next task.
>>
>> ch = nextch();
}
>>>Are these assumptions correct? I'm guessing the code is non-portable, so
does anyone have a neat(er) suggestion?

fetch more ch as long as isxdigit(ch) and you haven't gotten
more chars than you can handle, and store them into a buffer.
Then strtoul() specifying base 16.

Definitely a nice solution, but I think it will be hard to detect
overflows? My compiler documentation for strtoul says that it returns
ULONG_MAX on overflow, but how do I distinguish this from the case when I
encounter the actual ULONG_MAX value? This is why I am hand-coding this
thing, so that I can emit appropriate warning messages when such things
happen.
ok, so I read the rest of the strtoul docs and it says 'errno' is set for
overflow/underflow. Looks like this is my preferred solution, thanks for the
help.

James
Nov 8 '06 #4

P: n/a
Walter Roberson wrote:
In article <lt********************@pipex.net>,
James Brown <no*@home.netwrote:
I have a series of characters which I need to convert to integer values.
Each character is read in turn from a function 'nextch', and hex-digits are
identified by the isxdigit function - so I'm looking at '0' - '9', 'A' - 'Z'
and 'a' - 'z'.
Here is what I've got:
int num = 0;
int ch = nextch(); /* nextc obtains the next character value */
while(isxdigit(ch))

What if it was EOF ?
The loop exists. What of it?
{
if(isdigit(ch))
ch = ch - '0'; /* this is portable I believe */

Yes.
else
ch = (ch & ~0x20) - 'A' + 10; /* not sure if this is ok */

The & ~0x20 is a hidden toupper() and not portable to non-ASCII.

And as you had thought, 'A' through 'F' are not guaranteed to be
consequative or even increasing order.

num = num * 0x10 + ch;

What if you overflow your int ?
ch = nextch();
}
Are these assumptions correct? I'm guessing the code is non-portable, so
does anyone have a neat(er) suggestion?

fetch more ch as long as isxdigit(ch) and you haven't gotten
more chars than you can handle, and store them into a buffer.
Then strtoul() specifying base 16.

If you have particular reasons for handling the characters yourself,
then create a translation table of size UCHAR_MAX,
Assuming UCHAR_MAX is reasonably small.
and initialize it, tr['0'+i] = i for i from 0 to 9, and
tr['A'] = 10, tr['B'] = 11, etc., tr['a'] = 10, tr['b'] = 11, etc.,
then to do the conversion, just determine isxdigit(ch) and if so
then the converted value is tr[ch]. Yes, this has the potential
to waste UCHAR_MAX - 26 slots, but it is also a portable single-step
conversion with no math (other than normal array indexing)
A simple switch() will do the job too...

--
Peter

Nov 8 '06 #5

P: n/a
"James Brown" <no*@home.netwrites:
"Walter Roberson" <ro******@ibd.nrc-cnrc.gc.cawrote in message
news:ei**********@canopus.cc.umanitoba.ca...
[...]
>fetch more ch as long as isxdigit(ch) and you haven't gotten
more chars than you can handle, and store them into a buffer.
Then strtoul() specifying base 16.

Definitely a nice solution, but I think it will be hard to detect overflows?
My compiler documentation for strtoul says that it returns ULONG_MAX on
overflow, but how do I distinguish this from the case when I encounter the
actual ULONG_MAX value? This is why I am hand-coding this thing, so that I
can emit appropriate warning messages when such things happen.
This is explained in the documentation for strtoul(). On overflow, it
returns ULONG_MAX and sets errno to ERANGE. (You have to set errno to
0 before calling it.)

errno = 0;
result = strtoul(blah, blah, blah);
if (result == ULONG_MAX && errno == ERANGE) {
/* overflow */
}

--
Keith Thompson (The_Other_Keith) ks***@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.
Nov 8 '06 #6

P: n/a
"Peter Nilsson" <ai***@acay.com.auwrites:
Walter Roberson wrote:
>In article <lt********************@pipex.net>,
James Brown <no*@home.netwrote:
[...]
>while(isxdigit(ch))

What if it was EOF ?

The loop exists. What of it?
I think you mean the loop exits.

--
Keith Thompson (The_Other_Keith) ks***@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.
Nov 8 '06 #7

P: n/a
James Brown wrote:
>
.... snip ...
>
p.s. I derived this code from the lcc compiler sourcecode...
If you mean lcc-win32, that explains the non-portability.

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

P: n/a
On Wed, 2006-11-08 at 18:59 +0000, James Brown wrote:
It assumes that 'A' - 'F' are consecutive values
It assumes that 'a' - 'f' are consecutive, and are always 0x20 above their
'uppercase' counterparts.

Are these assumptions correct? I'm guessing the code is non-portable, so
does anyone have a neat(er) suggestion?
Here's a trick from /C Unleashed/, in a chapter (I believe) Richard
Heathfield wrote:

char *hex = "0123456789ABCDEF";

Then you have a number-to-hex converter right there:
hex[n] = n_16, 0 <= n <= 15.

--
Andrew Poelstra <http://www.wpsoftware.net>
For email, use 'apoelstra' at the above site.
"You're only smart on the outside." -anon.

Nov 9 '06 #9

P: n/a
Andrew Poelstra said:
Here's a trick from /C Unleashed/, in a chapter (I believe) Richard
Heathfield wrote:

char *hex = "0123456789ABCDEF";
How I wish I'd written const char *. Oh well.

--
Richard Heathfield
"Usenet is a strange place" - dmr 29/7/1999
http://www.cpax.org.uk
email: normal service will be restored as soon as possible. Please do not
adjust your email clients.
Nov 9 '06 #10

P: n/a
On Thu, 2006-11-09 at 00:45 +0000, Richard Heathfield wrote:
Andrew Poelstra said:
Here's a trick from /C Unleashed/, in a chapter (I believe) Richard
Heathfield wrote:

char *hex = "0123456789ABCDEF";

How I wish I'd written const char *. Oh well.
Actually, what you wrote was:

char Hex[] = "0123456789ABCDEF";

Sorry for misquoting you; I had written that, and then thought,
'Why would I want to modify that?', converted it from an array
to a pointer, and forgot to qualify it with const.

--
Andrew Poelstra <http://www.wpsoftware.net>
For email, use 'apoelstra' at the above site.
"You're only smart on the outside." -anon.

Nov 9 '06 #11

P: n/a
CBFalconer <cb********@yahoo.comwrites:
James Brown wrote:
>>
... snip ...
>>
p.s. I derived this code from the lcc compiler sourcecode...

If you mean lcc-win32, that explains the non-portability.
lcc is a different compiler, the one on which lcc-win32 was based.

Code that's part of an implementation doesn't have to be portable; if
there's some real advantage in using some non-portable solution, the
implementer is free to do so.

--
Keith Thompson (The_Other_Keith) ks***@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.
Nov 9 '06 #12

P: n/a
Andrew Poelstra said:
On Thu, 2006-11-09 at 00:45 +0000, Richard Heathfield wrote:
>Andrew Poelstra said:
Here's a trick from /C Unleashed/, in a chapter (I believe) Richard
Heathfield wrote:

char *hex = "0123456789ABCDEF";

How I wish I'd written const char *. Oh well.

Actually, what you wrote was:

char Hex[] = "0123456789ABCDEF";

Sorry for misquoting you;
No sweat. BTW it could still use a const. Mea culpa.

--
Richard Heathfield
"Usenet is a strange place" - dmr 29/7/1999
http://www.cpax.org.uk
email: normal service will be restored as soon as possible. Please do not
adjust your email clients.
Nov 9 '06 #13

P: n/a
Keith Thompson wrote:
>
.... snip ...
>
This is explained in the documentation for strtoul(). On overflow,
it returns ULONG_MAX and sets errno to ERANGE. (You have to set
errno to 0 before calling it.)

errno = 0;
result = strtoul(blah, blah, blah);
if (result == ULONG_MAX && errno == ERANGE) {
/* overflow */
}
IIRC this fails miserably when the user enters "-1", etc.

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

Nov 9 '06 #14

P: n/a
CBFalconer <cb********@yahoo.comwrites:
Keith Thompson wrote:
>>
... snip ...
>>
This is explained in the documentation for strtoul(). On overflow,
it returns ULONG_MAX and sets errno to ERANGE. (You have to set
errno to 0 before calling it.)

errno = 0;
result = strtoul(blah, blah, blah);
if (result == ULONG_MAX && errno == ERANGE) {
/* overflow */
}

IIRC this fails miserably when the user enters "-1", etc.
That depends on what you mean by "fails miserably". It treats "-1" as
a negative integer to be converted to unsigned long. The result is
ULONG_MAX; you can distinguish that from an overflow by checking
errno. If you want to reject negative literals, you need to check for
the '-' character before calling strtoul().

I'm not convinced that that's the ideal behavior, but it's how it's
defined.

--
Keith Thompson (The_Other_Keith) ks***@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.
Nov 9 '06 #15

P: n/a
Keith Thompson wrote:
CBFalconer <cb********@yahoo.comwrites:
>Keith Thompson wrote:
>>>
... snip ...
>>>
This is explained in the documentation for strtoul(). On overflow,
it returns ULONG_MAX and sets errno to ERANGE. (You have to set
errno to 0 before calling it.)

errno = 0;
result = strtoul(blah, blah, blah);
if (result == ULONG_MAX && errno == ERANGE) {
/* overflow */
}

IIRC this fails miserably when the user enters "-1", etc.

That depends on what you mean by "fails miserably". It treats "-1" as
a negative integer to be converted to unsigned long. The result is
ULONG_MAX; you can distinguish that from an overflow by checking
errno. If you want to reject negative literals, you need to check for
the '-' character before calling strtoul().

I'm not convinced that that's the ideal behavior, but it's how it's
defined.
Exactly, and I define that as 'fails miserably'. I want to know
whenever a user enters something outside its defined principle
range. I have input routines that reject such.

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

Nov 9 '06 #16

P: n/a
Andrew Poelstra skrev:
Here's a trick from /C Unleashed/, in a chapter (I believe) Richard
Heathfield wrote:
The trick predate this book... :)
char *hex = "0123456789ABCDEF";

Then you have a number-to-hex converter right there:
hex[n] = n_16, 0 <= n <= 15.
Which can be used for binary-to-hex converter, however OP asked for a
hex-to-binary converter.

What is needed, is something ala:

unsigned char hex[UCHAR_MAX] = {0};

hex['0'] = 0;
hex['1'] = 1;
hex['2'] = 2;
....
hex['F'] = 15;

/* todo: check input has even lenght */
/* todo: check for buffer overflow */

for(i=j=0; i < in_len; i+=2, j++)
{
if ( isxdigit(in[i]) && isxdigit(in[i+1]) )
{
binary[ j ] = hex[ in[i] ] << 4 | hex[ in[i+1] ];
}
else
{
assert( !"function xxx: non-hex input" );
/* todo: handle non-hex input */
}
}

--
Tor <torust AT online DOT no>
"To this day, many C programmers believe that 'strong typing' just
means pounding extra hard on the keyboard". PvdL

Nov 9 '06 #17

P: n/a
Tor Rustad said:
Andrew Poelstra skrev:
>Here's a trick from /C Unleashed/, in a chapter (I believe) Richard
Heathfield wrote:

The trick predate this book... :)
Certainly. I didn't even think of it as a trick - just as... um... oh yeah,
programming.

--
Richard Heathfield
"Usenet is a strange place" - dmr 29/7/1999
http://www.cpax.org.uk
email: normal service will be restored as soon as possible. Please do not
adjust your email clients.
Nov 9 '06 #18

P: n/a
James Brown wrote:
All,

I have a series of characters which I need to convert to integer values.
Each character is read in turn from a function 'nextch', and hex-digits are
identified by the isxdigit function - so I'm looking at '0' - '9', 'A' - 'Z'
and 'a' - 'z'.
[...]
Are these assumptions correct? I'm guessing the code is non-portable, so
does anyone have a neat(er) suggestion?
As others have said, the code is not portable.

How about this for a suggestion? It includes overflow detection.

#include <stdio.h>
#include <ctype.h>
#include <limits.h>

int nextch(void)
{
return getchar();
}

int main(void)
{
int ch;
unsigned long num = 0;
while(isxdigit(ch = nextch()) && num <= ULONG_MAX / 16)
{
num <<= 4;
switch(ch)
{
case 'f': case 'F': num++;
case 'e': case 'E': num++;
case 'd': case 'D': num++;
case 'c': case 'C': num++;
case 'b': case 'B': num++;
case 'a': case 'A': num++;
case '9': num++;
case '8': num++;
case '7': num++;
case '6': num++;
case '5': num++;
case '4': num++;
case '3': num++;
case '2': num++;
case '1': num++;
}
}
if(isxdigit(ch))
{
fprintf(stderr, "Overflow\n");
}
else
{
printf("hex = %lX, dec = %lu\n", num, num);
}
return 0;
}

GCC turns this switch into a jump table. It subtracts 49 from ch and
jumps to the given location in the table:

int eax = ch - '1';
int e
num <<= 4;
leal -49(%edx), %eax /* eax = ch - '1' */
sall $4, %ecx /* num <<= 4 */
cmpl $53, %eax /* compare eax with 'f' - '1' */
movl %ecx, %ebx /* ebx = num */
ja L33 /* if(eax 'f' - 1') goto default */
jmp *L27(,%eax,4) /* goto L27[eax]
.section .rdata,"dr"
.align 4
L27:
.long L26
.long L25
.long L24
.long L23
.long L22
.long L21
.long L20
.long L19
.long L18
.long L33
.long L33
.long L33
.long L33
.long L33
.long L33
.long L33
.long L17
.long L15
.long L13
.long L11
.long L9
.long L7
.long L33
.long L33
.long L33
.long L33
.long L33
.long L33
.long L33
.long L33
.long L33
.long L33
.long L33
.long L33
.long L33
.long L33
.long L33
.long L33
.long L33
.long L33
.long L33
.long L33
.long L33
.long L33
.long L33
.long L33
.long L33
.long L33
.long L17
.long L15
.long L13
.long L11
.long L9
.long L7
.text
L7:
leal 1(%ecx), %ebx
L9:
incl %ebx
L11:
incl %ebx
L13:
incl %ebx
L15:
incl %ebx
L17:
incl %ebx
L18:
incl %ebx
L19:
incl %ebx
L20:
incl %ebx
L21:
incl %ebx
L22:
incl %ebx
L23:
incl %ebx
L24:
incl %ebx
L25:
incl %ebx
--
Simon.
Nov 10 '06 #19

P: n/a
Andrew Poelstra wrote:
>>
>>Here's a trick from /C Unleashed/, in a chapter (I believe) Richard
Heathfield wrote:

char *hex = "0123456789ABCDEF";

Actually, what you wrote was:

char Hex[] = "0123456789ABCDEF";

Sorry for misquoting you; I had written that, and then thought,
'Why would I want to modify that?', converted it from an array
to a pointer, and forgot to qualify it with const.
Can you explain how you got from "Why would I want to
modify that?", to converting it to a pointer ?

My preference would be:
const char Hex[] = "0123456789ABCDEF";

Nov 12 '06 #20

P: n/a
On 2006-11-12, Old Wolf <ol*****@inspire.net.nzwrote:
Andrew Poelstra wrote:
>>>
Here's a trick from /C Unleashed/, in a chapter (I believe) Richard
Heathfield wrote:

char *hex = "0123456789ABCDEF";

Actually, what you wrote was:

char Hex[] = "0123456789ABCDEF";

Sorry for misquoting you; I had written that, and then thought,
'Why would I want to modify that?', converted it from an array
to a pointer, and forgot to qualify it with const.

Can you explain how you got from "Why would I want to
modify that?", to converting it to a pointer ?
Instead of creating an array of chars, I'll just point to a
string literal, which I may not modify.
My preference would be:
const char Hex[] = "0123456789ABCDEF";
Indeed. Perhaps I should have found the quote in the book before
poorly paraphrasing it. :-)

Nov 12 '06 #21

P: n/a
"Old Wolf" <ol*****@inspire.net.nzwrites:
My preference would be:
const char Hex[] = "0123456789ABCDEF";
I'd add "static".
--
"I should killfile you where you stand, worthless human." --Kaz
Nov 12 '06 #22

P: n/a
Ben Pfaff wrote:
"Old Wolf" <ol*****@inspire.net.nzwrites:
My preference would be:
const char Hex[] = "0123456789ABCDEF";

I'd add "static".
If it's outside of a function then I would agree, to prevent the
compiler making it an external symbol. If it is within the
function then the "static" keyword would seem to not change
the observable behaviour, so I guess you would only add it
if you didn't trust your compiler!

Nov 13 '06 #23

P: n/a
"Old Wolf" <ol*****@inspire.net.nzwrites:
Ben Pfaff wrote:
>"Old Wolf" <ol*****@inspire.net.nzwrites:
My preference would be:
const char Hex[] = "0123456789ABCDEF";

I'd add "static".

If it's outside of a function then I would agree, to prevent the
compiler making it an external symbol. If it is within the
function then the "static" keyword would seem to not change
the observable behaviour, so I guess you would only add it
if you didn't trust your compiler!
In a function, there is an observable difference in that the
version without `const' has lifetime only during an execution of
the function. It's probably not important in this case because
it's unlikely that this string would be returned to a caller.
--
"When in doubt, treat ``feature'' as a pejorative.
(Think of a hundred-bladed Swiss army knife.)"
--Kernighan and Plauger, _Software Tools_
Nov 13 '06 #24

P: n/a
Old Wolf wrote:
Ben Pfaff wrote:
>"Old Wolf" <ol*****@inspire.net.nzwrites:
>>My preference would be:
const char Hex[] = "0123456789ABCDEF";

I'd add "static".

If it's outside of a function then I would agree, to prevent the
compiler making it an external symbol. If it is within the
function then the "static" keyword would seem to not change
the observable behaviour, so I guess you would only add it
if you didn't trust your compiler!
The 'static' gets it initialized once and for all at compile time,
rather than by executing local code on each entry into the
routine. This reduces run time.

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

P: n/a
CBFalconer wrote:
Old Wolf wrote:
Ben Pfaff wrote:
"Old Wolf" <ol*****@inspire.net.nzwrites:

My preference would be:
const char Hex[] = "0123456789ABCDEF";

I'd add "static".
If it's outside of a function then I would agree, to prevent the
compiler making it an external symbol. If it is within the
function then the "static" keyword would seem to not change
the observable behaviour, so I guess you would only add it
if you didn't trust your compiler!

The 'static' gets it initialized once and for all at compile time,
rather than by executing local code on each entry into the
routine. This reduces run time.
In theory, possibly. Since there's no difference in observable
behaviour, the compiler is quite entitled to do the same thing
in practice , regardless of whether 'static' is present or not.

In fact I'd wager that most compilers would not reinitialize
the non-static array every time the function is entered.

Nov 13 '06 #26

P: n/a
Old Wolf wrote:
CBFalconer wrote:
>Old Wolf wrote:
>>Ben Pfaff wrote:
"Old Wolf" <ol*****@inspire.net.nzwrites:

My preference would be:
const char Hex[] = "0123456789ABCDEF";

I'd add "static".

If it's outside of a function then I would agree, to prevent the
compiler making it an external symbol. If it is within the
function then the "static" keyword would seem to not change
the observable behaviour, so I guess you would only add it
if you didn't trust your compiler!

The 'static' gets it initialized once and for all at compile time,
rather than by executing local code on each entry into the
routine. This reduces run time.

In theory, possibly. Since there's no difference in observable
behaviour, the compiler is quite entitled to do the same thing
in practice , regardless of whether 'static' is present or not.

In fact I'd wager that most compilers would not reinitialize
the non-static array every time the function is entered.
You'ld be wrong. Most compilers implement automatic storage on a
stack, and that content is unknown on function entry. Without
initialization code the operation would be wrong.

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

Nov 13 '06 #27

P: n/a
2006-11-13 <45***************@yahoo.com>,
CBFalconer wrote:
Old Wolf wrote:
>CBFalconer wrote:
>>Old Wolf wrote:
Ben Pfaff wrote:
"Old Wolf" <ol*****@inspire.net.nzwrites:
>
>My preference would be:
> const char Hex[] = "0123456789ABCDEF";
>
I'd add "static".

If it's outside of a function then I would agree, to prevent the
compiler making it an external symbol. If it is within the
function then the "static" keyword would seem to not change
the observable behaviour, so I guess you would only add it
if you didn't trust your compiler!

The 'static' gets it initialized once and for all at compile time,
rather than by executing local code on each entry into the
routine. This reduces run time.

In theory, possibly. Since there's no difference in observable
behaviour, the compiler is quite entitled to do the same thing
in practice , regardless of whether 'static' is present or not.

In fact I'd wager that most compilers would not reinitialize
the non-static array every time the function is entered.

You'ld be wrong. Most compilers implement automatic storage on a
stack, and that content is unknown on function entry. Without
initialization code the operation would be wrong.
It doesn't need "initialization code" if you can't tell whether it's
there - all it has to do is put it somewhere other than on the stack,
which it is perfectly entitled to do.
Nov 13 '06 #28

P: n/a
CBFalconer wrote:
Old Wolf wrote:
CBFalconer wrote:
Old Wolf wrote:
Ben Pfaff wrote:
"Old Wolf" <ol*****@inspire.net.nzwrites:

My preference would be:
const char Hex[] = "0123456789ABCDEF";

I'd add "static".

If it's outside of a function then I would agree, to prevent the
compiler making it an external symbol. If it is within the
function then the "static" keyword would seem to not change
the observable behaviour, so I guess you would only add it
if you didn't trust your compiler!

The 'static' gets it initialized once and for all at compile time,
rather than by executing local code on each entry into the
routine. This reduces run time.
In theory, possibly. Since there's no difference in observable
behaviour, the compiler is quite entitled to do the same thing
in practice , regardless of whether 'static' is present or not.

In fact I'd wager that most compilers would not reinitialize
the non-static array every time the function is entered.

You'ld be wrong. Most compilers implement automatic storage on a
stack, and that content is unknown on function entry. Without
initialization code the operation would be wrong.
There's no requirement for storage to be on a stack,
and it would seem sensible for an array that never
changes and only needs to be initialized at most once,
to not be placed on a stack.

Nov 13 '06 #29

This discussion thread is closed

Replies have been disabled for this discussion.