int * vs char *

T

Tim Rentsch

Keith Thompson said:
Valid, but I think a lot of such code, perhaps most of it, has been
fixed by necessity, after it blew up when it was recompiled by a
compiler that makes literals non-writable.

Certainly a lot of it has. But it would be nice to have
a choice, especially since the problems may manifest more
subtly than having code blow up (eg, overlapping different
string literals in writable memory).

That could be done by an option that just forces literals to unique
locations without making them writable.

Sure, but an option to have literals be writable gets both.
If I were writing a compiler I'd rather have to provide
only one option rather than two.

Ok, but I don't think I've ever felt the need to do that.

Me either, but then I tend to use debuggers in rather
simple ways, and I know there are developers for whom
the exploratory capabilities of their debuggers is
quite valuable.

We'd get the benefit of a guarantee that programs accidentally
attempt to write string literals will be caught and fixed more
easily, regardless of which conforming compiler we're using.

Some developers would benefit from such a guarantee. Most
developers already have the benefit available to them.
A hypothetical compiler option doesn't do me much good if the
compiler I'm using doesn't provide it (recompiling with a different
compiler isn't always an option).

Oh, the other compiler doesn't have to be used to produce the
object files; it can be used _in addition to_ the particular
target compiler, just to provide extra error checking. Granted,
there can be discrepancies between the two compilations if there
is platform-specific conditional compilation, but programs that
make extensive use of that have much deeper problems than string
literals.

To say this another way - can you name one real-world example
of a program where it can't easily be checked for string literal
non-const-ness?

Similar arguments could be made in favor of making modifying a
const-qualified object undefined behavior rather than a constraint
violation:

const int x = 42;
x = 43;

The two cases don't seem sufficiently analogous to draw
any useful conclusions.

In my opinion, the only good reason to consider allowing string
literals to be modifiable is for compatibility with very old
implementations. I suspect that if string literals had been const
from the beginning (which would have required inventing "const"
many years sooner), we wouldn't be having this discussion.

A better option would be for the Standard to mandate a compiler
option to give a diagnostic if a string literal is used as a
'char *' rather than a 'const char *'. Some groups like 'const'
and use it a lot; others use it only when necessary. I think
it's better not to change the language itself but simply make
sure better tools are there for people who want or need them, and
let different groups decide independently. This approach also is
better suited for acceptance in the development community, not
to mention allowing easier transitioning of old programs.
 
S

Shao Miller

Compare to the only option C provides:

char *strchr(const char *s, int c);

This takes a const or non-const argument but always returns a non-const
pointer; the potential loss of const-ness invites bugs. Thanks to
overloading, the C++ version is able to return a pointer that matches
the const-ness of its argument, preventing bugs.

A fellow yesterday advised of another strategy, using a GCC extension:

#define strchr(s, c) ((__typeof__(s)) (strchr((s), (c)))

That is, casting the result to the original type of 's'. Heheheh.
 
D

Dr Nick

Shao Miller said:
A fellow yesterday advised of another strategy, using a GCC extension:

#define strchr(s, c) ((__typeof__(s)) (strchr((s), (c)))

That is, casting the result to the original type of 's'. Heheheh.

That's either very neat or unutterably ghastly. I'm still thinking
about which it is.
 
H

Harald van Dijk

That's either very neat or unutterably ghastly.  I'm still thinking
about which it is.

I'm going for ghastly, because it gives an error when s is an array,
and it gives the wrong result type when s is a pointer to (const) void.
 
S

Shao Miller

I'm going for ghastly, because it gives an error when s is an array,
and it gives the wrong result type when s is a pointer to (const) void.

(Note I had missed a right parenthesis at the end.)

That rings quite true. :)

Hmmm... I was actually just guessing at the macro based on what the
fellow had said, but considering your array note, perhaps it was more like:

#define strchr(s, c) (*((__typeof__(s) *) (strchr((s), (c)))))

It might be interesting if there was a '__constof__(type-name)' and/or
'__constof__(object)' that could expand to 'const' or nothing, as
appropriate.

const char * foo;
/* The next type is 'const char' */
typedef __constof__(*foo) char foo_base_t;
/* The next type is silly */
typedef int * __constof__(foo_base_t) bar;

Uhhh... :S

#define strchr(s, c) ((__constof__(*(s)) char *) (strchr((s), (c))))
 
J

Joel C. Salomon

A fellow yesterday advised of another strategy, using a GCC extension:

#define strchr(s, c) ((__typeof__(s)) (strchr((s), (c)))

That is, casting the result to the original type of 's'. Heheheh.

I proposed another version on comp.std.c a few months back, using the
C1x proposed _Generic keyword. As fixed by Ben Bacarisse:

#define strchr(str, chr) \
_Generic((str), \
const void *: (const char *)strchr((str), (chr)), \
const char *: (const char *)strchr((str), (chr)), \
default: strchr((str), (chr)) \
)

(See the thread "_Generic and defining NELEM(arr)".)

--Joel
 
S

Shao Miller

I proposed another version on comp.std.c a few months back, using the
C1x proposed _Generic keyword. As fixed by Ben Bacarisse:

#define strchr(str, chr) \
_Generic((str), \
const void *: (const char *)strchr((str), (chr)), \
const char *: (const char *)strchr((str), (chr)), \
default: strchr((str), (chr)) \
)

(See the thread "_Generic and defining NELEM(arr)".)

Very nice. :) I wonder how that plays with arrays... If the
controlling expression is not evaluated[6.5.1.1p3], then the type could
be an array type... Perhaps another line?

const char[]: ((const char *) strchr((str), (chr))), \

'_Generic' isn't mentioned in 6.3.2.1p3, but this still gives me pause.
 
P

Phil Carmody

Shao Miller said:
(Note I had missed a right parenthesis at the end.)

That rings quite true. :)

Hmmm... I was actually just guessing at the macro based on what the
fellow had said, but considering your array note, perhaps it was more
like:

#define strchr(s, c) (*((__typeof__(s) *) (strchr((s), (c)))))

How about just:

#define strchr(s, c) ((__typeof__(&*s)) (strchr((s), (c))))

?
It might be interesting if there was a '__constof__(type-name)' and/or
'__constof__(object)' that could expand to 'const' or nothing, as
appropriate.

That I like. A lot. Get it in GCC, and I'll be an early adopter.

Phil
 
P

Phil Carmody

Phil Carmody said:
�â�����〮������⹣������ਾâ���㈰ㄱ‱㌺㌹Ⱐ���â¶ï¿½â„ij����ਾ‾â����‷���Ⱐ�âŽï¿½ï¿½ãŒ­ï¿½ï¿½â¸®ï¿½ï¿½ï¿½ï¿½ï¿½âµ¡ï¿½ï¿½ï¿½â¹¯ï¿½â¹µï¿½â€ ï¿½ï¿½ï¿½à¨¾â€¾ï¿½ï¿½ï¿½â�����⹭�⸮⹀�����†�����������â¹ï¿½ï¿½ï¿½ï¿½â¡ï¿½ï¿½ï¿½â¯ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½â° ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½à¨¾â€¾ï¿½ï¿½ï¿½ï¿½â€ â€£ï¿½ï¿½ï¿½â³ï¿½ï¿½ï¿½ï¿½â£â¤ â ¨ï¿½ï¿½ï¿½ï¿½ï¿½â¡³â¤©â€¨ï¿½ï¿½ï¿½â ¨ï¿½â° â¡£â¤©â¤Šï¿½ï¿½à¨¾â€¾ï¿½â”���Ⱐ���������â´ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½â´ï¿½ï¿½ï¿½â€§ï¿½â¸ âˆï¿½ï¿½ï¿½â¸Šï¿½ï¿½à¨¾â€¾ï¿½ï¿½ï¿½â³â¥ï¿½ï¿½ï¿½ï¿½ï¿½â®ï¿½ï¿½ï¿½âµï¿½ï¿½ï¿½ï¿½ï¿½â§ï¿½ï¿½ï¿½â¸ â‰â­â³ï¿½ï¿½â´ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½â¡ï¿½ï¿½â·ï¿½ï¿½â©ï¿½ï¿½â¸Šï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½â¢ï¿½ï¿½ï¿½â©ï¿½ï¿½ï¿½ï¿½ï¿½â¥ï¿½ï¿½â·ï¿½ï¿½ï¿½ï¿½â¡ï¿½ï¿½ï¿½ï¿½à¨¾â€¾â¡ï¿½â©ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½â´ï¿½ï¿½ï¿½ï¿½â³â©ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½â€¨ï¿½ï¿½ï¿½â¶ï¿½ï¿½à¨¾â€Šï¿½â¡Žï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½â¡â²ï¿½ï¿½â°ï¿½ï¿½ï¿½ï¿½ï¿½â¡ï¿½ï¿½ï¿½ï¿½ï¿½â¤Šï¿½à¨¾â”����������⸠�ਾ ���⸮⸠â‰â·ï¿½â¡ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½â§ï¿½ï¿½ï¿½ï¿½ï¿½â´ï¿½â­ï¿½ï¿½â¢ï¿½ï¿½â¯ï¿½ï¿½ï¿½â´ï¿½à¨¾â¦ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½â° ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½â¡ï¿½ï¿½â®ï¿½ï¿½â°ï¿½ï¿½ï¿½â©ï¿½ï¿½ï¿½ï¿½ï¿½à¨¾â¬ï¿½ï¿½à¨¾â€Šï¿½â€ â€£ï¿½ï¿½ï¿½â³ï¿½ï¿½ï¿½ï¿½â£â¤ â ªâ ¨ï¿½ï¿½ï¿½ï¿½ï¿½â¡³â¤ â¨©â€¨ï¿½ï¿½ï¿½â ¨ï¿½â° â¡£â¤©â¤©â¤Šà©ˆï¿½â¡ï¿½ï¿½âªï¿½ï¿½à¨Šâ¤ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½â¡³â° ï¿½â€¨â¡Ÿï¿½ï¿½ï¿½ï¿½ï¿½â˜ªï¿½â¤ â¡³ï¿½ï¿½ï¿½â¡³â¤¬â€¨ï¿½â¤©â¤Šà¨¿â€Šà¨¾â‰ï¿½ï¿½ï¿½ï¿½ï¿½â©ï¿½ï¿½ï¿½ï¿½ï¿½â©ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½âŸï¿½ï¿½ï¿½ï¿½ï¿½â¡´ï¿½ï¿½ï¿½ï¿½â¤§â¡ï¿½â½¯ï¿½ï¿½âŸï¿½ï¿½ï¿½ï¿½ï¿½â¡¯ï¿½ï¿½ï¿½âœ ï¿½ï¿½â£ï¿½ï¿½â¥ï¿½ï¿½ï¿½ï¿½â€§ï¿½ï¿½ï¿½â¯ï¿½ï¿½ï¿½ï¿½ï¿½â¡ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½à¨Šï¿½ï¿½â‰â¬ï¿½ï¿½ââ¬ï¿½â¸ ï¿½ï¿½ï¿½â©ï¿½ï¿½ï¿½â¡ï¿½â‰â¬ï¿½ï¿½â¡ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½à¨Šï¿½ï¿½à¨­â´ à¨¢ï¿½â¬ï¿½ï¿½â¹ï¿½â«ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½â����⸢ਢ��⸠���â·ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½â¸¢â€­â´ ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½

No idea what happened there, that's all "?"s to me. I certainly never consciously chose
Content-Type: text/plain; charset=utf-16be
Google groups, no matter how much it sucks, shows that there's a post hidden behind that noise:
http://groups.google.com/group/comp.lang.c/msg/4bbd1eab45333db5
 
S

Shao Miller

Phil Carmody said:
[...uhh...]

No idea what happened there, that's all "?"s to me. I certainly never consciously chose
Content-Type: text/plain; charset=utf-16be
Google groups, no matter how much it sucks, shows that there's a post hidden behind that noise:
http://groups.google.com/group/comp.lang.c/msg/4bbd1eab45333db5

Doubly-odd. It showed up weird in Thunderbird, so I went to Google
Groups to confirm. That's how I saw it there, too. I actually replied
from Google Groups as Thunderbird wouldn't send my response (due to the
quoting?). :S Anyway...
 
S

Stephen Sprunk

Phil Carmody said:
[...uhh...]

No idea what happened there, that's all "?"s to me. I certainly never
consciously chose
Content-Type: text/plain; charset=utf-16be
Google groups, no matter how much it sucks, shows that there's a post
hidden behind that noise:
http://groups.google.com/group/comp.lang.c/msg/4bbd1eab45333db5

Doubly-odd. It showed up weird in Thunderbird, so I went to Google
Groups to confirm. That's how I saw it there, too. I actually replied
from Google Groups as Thunderbird wouldn't send my response (due to the
quoting?). :S Anyway...

Thunderbird displays the message properly (and allows responses) when
forced to interpret the message as UTF-8 rather than as the UTF-16BE
indicated in the header noted above. I suspect other modern readers
would as well, but one has to think to try it.

S
 

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,776
Messages
2,569,603
Members
45,201
Latest member
KourtneyBe

Latest Threads

Top