Yet another nitpicky style question

  • Thread starter Christopher Benson-Manica
  • Start date
T

Tom St Denis

Christopher Benson-Manica said:
Do you prefer *my_string or my_string[0]? Why?

depends. somestruct->charptr[0] is easier to read than
*(somestruct->charptr) I think...

But

*charptr++ = 'a';

Is cleaner than

charptr[0] = 'a'; ++charptr;

Tom
 
T

Tom St Denis

Tom St Denis said:
Christopher Benson-Manica said:
Do you prefer *my_string or my_string[0]? Why?

depends. somestruct->charptr[0] is easier to read than
*(somestruct->charptr) I think...

Note: [before anyone gets wise] I normally put () around my member
references just to make the intent clear.

Tom
 
C

Charles Harrison Caudill

Tom St Denis said:
depends. somestruct->charptr[0] is easier to read than
*(somestruct->charptr) I think...
Note: [before anyone gets wise] I normally put () around my member
references just to make the intent clear.

I'm assuming then that the '->' binds more tightly than the '*'?
 
T

Tom St Denis

Charles Harrison Caudill said:
Tom St Denis said:
depends. somestruct->charptr[0] is easier to read than
*(somestruct->charptr) I think...
Note: [before anyone gets wise] I normally put () around my member
references just to make the intent clear.

I'm assuming then that the '->' binds more tightly than the '*'?

Yes. Just

*somestruct->charptr

is harder for me to read than

*(somestruct->charptr)

Even though they mean the same thing [the actual "wrong" code alluded to
would be (*somestruct)->charptr which means something else].

Tom
 
L

Leor Zolman

Do you prefer *my_string or my_string[0]? Why?

First off, I'm wondering whether you're asking about the limited case
of fetching just the first character of an array, or the more general
question "when is it better to traverse an array with a pointer vs.
using subscripts"? But for the most part, I think both questions share
the same answer [although the latter general question invites
performance-related arguments, most of which probably wouldn't stand
up to close scrutiny in this group ;-) ]

I'd ask myself whether one way or the other better reflects the task
at hand ("better" in this case having a high probability of being
decided on a subjective basis) and/or contributes to a more consistent
approach. Let's see, an example would be good...

#include <ctype.h>

int startsWithId(char const str[])
{
return isupper(str[0]) || str[0] == '_'; // consistent
// or (pick ONE):
return isalpha(*str) || *str == '_'; // not consistent?
}

So first I'd decide whether I wanted to represent the parameter as an
array or as a pointer, and then I'd be consistent in the body of the
function. Or, the process may run in reverse: I'll first find the more
natural notation for the implementation, and then make sure the
declaration is consistent with /that/.

In the example above, I really don't have a preference between
declaring str as an array or as a pointer, but whichever I picked, I'd
just try to be consistent.


Leor Zolman
BD Software
(e-mail address removed)
www.bdsoft.com -- On-Site Training in C/C++, Java, Perl & Unix
C++ users: Download BD Software's free STL Error Message
Decryptor at www.bdsoft.com/tools/stlfilt.html
 
L

Leor Zolman

int startsWithId(char const str[])
{
return isupper(str[0]) || str[0] == '_'; // consistent
// or (pick ONE):
return isalpha(*str) || *str == '_'; // not consistent?
}

Darn it, that second one was supposed to be "isupper" also. Now why
couldn't the compiler have caught that for me? Compilers and
spell-checkers...


Leor Zolman
BD Software
(e-mail address removed)
www.bdsoft.com -- On-Site Training in C/C++, Java, Perl & Unix
C++ users: Download BD Software's free STL Error Message
Decryptor at www.bdsoft.com/tools/stlfilt.html
 
L

Leor Zolman

int startsWithId(char const str[])
{
return isupper(str[0]) || str[0] == '_'; // consistent
// or (pick ONE):
return isalpha(*str) || *str == '_'; // not consistent?
}

I'm /not/ having a good day. The /first/ one is supposed to be
"isalpha". Grrr. (That's what I get for switching my example in
mid-stride.)

Leor Zolman
BD Software
(e-mail address removed)
www.bdsoft.com -- On-Site Training in C/C++, Java, Perl & Unix
C++ users: Download BD Software's free STL Error Message
Decryptor at www.bdsoft.com/tools/stlfilt.html
 
D

Dan Pop

In said:
Do you prefer *my_string or my_string[0]? Why?

It depends on the context. If I need it to access only the character
at that address, it's going to be pointer dereferencing syntax, if
I need to access more characters, at various offsets, it will be the
array access syntax.

Examples:

if (*p == 'a') ...

if (p[0] == 'a' && p[1] == 'b') ...

but never the equivalent:

if (*p == 'a' && p[1] == 'b') ...

Dan
 
P

Peter Nilsson

Leor Zolman said:
int startsWithId(char const str[])
{
return isupper(str[0]) || str[0] == '_'; // consistent
// or (pick ONE):
return isalpha(*str) || *str == '_'; // not consistent?
}

I'm /not/ having a good day. The /first/ one is supposed to be
"isalpha". Grrr. (That's what I get for switching my example in
mid-stride.)

The argument to either isxxxx call should be cast to unsigned char.
 
R

Richard Heathfield

Peter said:
Leor Zolman said:
int startsWithId(char const str[])
{
return isupper(str[0]) || str[0] == '_'; // consistent
// or (pick ONE):
return isalpha(*str) || *str == '_'; // not consistent?
}

I'm /not/ having a good day. The /first/ one is supposed to be
"isalpha". Grrr. (That's what I get for switching my example in
mid-stride.)

The argument to either isxxxx call should be cast to unsigned char.

Why? (That is, I know why you're saying it, but have you thought about the
consequences?)

I think it would be better to check whether the value you're going to pass
is /changed/ if you convert it to unsigned char. If so, then you're not
really testing what you think you're testing. And if not, why cast?

Thus:

if(ch == (unsigned char)ch)
{
Might as well just call isalpha(ch);
}
else
{
Well, isalpha would only return 0 anyway, and you've learned something
important about ch.
}
 
P

Peter Nilsson

Richard Heathfield said:
Peter said:
Leor Zolman said:
int startsWithId(char const str[])
{
return isupper(str[0]) || str[0] == '_'; // consistent
// or (pick ONE):
return isalpha(*str) || *str == '_'; // not consistent?
}

I'm /not/ having a good day. The /first/ one is supposed to be
"isalpha". Grrr. (That's what I get for switching my example in
mid-stride.)

The argument to either isxxxx call should be cast to unsigned char.

Why? (That is, I know why you're saying it, but have you thought about the
consequences?)

I think it would be better to check whether the value you're going to pass
is /changed/ if you convert it to unsigned char.

I don't think it's unreasonable to assume that negative characters are
changed _back_ to their original value [in all but a handful of exceptional
cases, e.g. 1c or sm machines where -0 may convert 'back' to 0 rather than
255 or 128 say.]

Given a choice between potential undefined behaviour and well defined
behaviour (on 'sane' implemetations), I choose the latter. [Presumably your
book says the same?] Anyway...
If so, then you're not
really testing what you think you're testing. And if not, why cast?

Thus:

if(ch == (unsigned char)ch)
{
Might as well just call isalpha(ch);
}
else
{
Well, isalpha would only return 0 anyway,
Huh?

and you've learned something
important about ch.
}

AFAICS, the program won't have learnt anything at all from the test. What
stops a character from being (originally sourced as) an alpha character,
having a negative value in a plain char representation in non "C" locales?

If Leor wanted purely to test for characters in the set A-Za-z, then the
only sure way (from a strict conformance POV) is to explicity compare
against that character set.

What am I missing?
 
R

Richard Heathfield

Peter said:
Richard Heathfield said:
Why? (That is, I know why you're saying it, but have you thought about
the consequences?)

I think it would be better to check whether the value you're going to
pass is /changed/ if you convert it to unsigned char.

I don't think it's unreasonable to assume that negative characters are
changed _back_ to their original value [in all but a handful of
exceptional cases, e.g. 1c or sm machines where -0 may convert 'back' to 0
rather than 255 or 128 say.]

Changed back /when/? Not in isalpha(), that's for sure. Consider this code
(in a char == signed environment):

char c = somenegativevalue;
unsigned char uc = c;
int i = uc;
printf("%d\n", i);

This is going to print a non-negative value. i == c is bound to compare
false.
 
P

Peter Nilsson

Richard Heathfield said:
Peter said:
Richard Heathfield said:
Peter Nilsson wrote:

The argument to either isxxxx call should be cast to unsigned char.

Why? (That is, I know why you're saying it, but have you thought about
the consequences?)

I think it would be better to check whether the value you're going to
pass is /changed/ if you convert it to unsigned char.

I don't think it's unreasonable to assume that negative characters are
changed _back_ to their original value [in all but a handful of
exceptional cases, e.g. 1c or sm machines where -0 may convert 'back' to 0
rather than 255 or 128 say.]

Changed back /when/? Not in isalpha(), that's for sure. Consider this code
(in a char == signed environment):

char c = somenegativevalue;
unsigned char uc = c;
int i = uc;
printf("%d\n", i);

This is going to print a non-negative value. i == c is bound to compare
false.

The case I'm thinking of is the more usual one where a character is
assigned from input...

char text[100];
fgets(text, sizeof text, stdin);

The user might enter an extended character, é (e accent) say, which
would have a valid unsigned char value within an int, but (may) have a
negative representation as a (signed) plain char element of text on
conversion from int to char.

I assume (by expectation of reasonable QoI rather than the standard)
that the conversion from char to unsigned char would restore the
original character.

The vast majority of implementations I've been exposed to (limited I
grant you) with extended character support for non-C locales still
have signed plain char. In addition, these implementations convert a
_lot_ of characters to negative values within plain char. It would be
quite tediously difficult to use these implementations reliably, if
the conversion back to unsigned char did not restore the original
character.
 
C

CBFalconer

Leor said:
Christopher Benson-Manica said:
Do you prefer *my_string or my_string[0]? Why?

First off, I'm wondering whether you're asking about the limited case
of fetching just the first character of an array, or the more general
question "when is it better to traverse an array with a pointer vs.
using subscripts"? But for the most part, I think both questions share
the same answer [although the latter general question invites
performance-related arguments, most of which probably wouldn't stand
up to close scrutiny in this group ;-) ]

I have two questions:

1. Does the OP want to access an array or the first component
of that array? They are not the same thing.

2. Why does your software change the subject to ">"?
 
L

Leor Zolman

Leor said:
Christopher Benson-Manica said:
Do you prefer *my_string or my_string[0]? Why?

First off, I'm wondering whether you're asking about the limited case
of fetching just the first character of an array, or the more general
question "when is it better to traverse an array with a pointer vs.
using subscripts"? But for the most part, I think both questions share
the same answer [although the latter general question invites
performance-related arguments, most of which probably wouldn't stand
up to close scrutiny in this group ;-) ]

I have two questions:

1. Does the OP want to access an array or the first component
of that array? They are not the same thing.

2. Why does your software change the subject to ">"?

Can't blame Agent for that one. I must've done it somehow.

Sorry for the delay-- just back from 6 days' vacation...and 1053 new
messages downloaded here. Is it any wonder some folks would prefer to not
expand the scope of the group?
-leor



Leor Zolman
BD Software
(e-mail address removed)
www.bdsoft.com -- On-Site Training in C/C++, Java, Perl & Unix
C++ users: Download BD Software's free STL Error Message
Decryptor at www.bdsoft.com/tools/stlfilt.html
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,769
Messages
2,569,579
Members
45,053
Latest member
BrodieSola

Latest Threads

Top