How to identify a pointer to a string literal

W

weaselboy1976

Hello,

If we have c code like what's below, we will get an error because in
the stringManipulator function we attempt to modify a string literal on
the second call to the function. My question is: in the
stringManipulator function, is there any way to identify if the char*
is pointing to writable memory space to to a string literal?

Sure, the example is trivial, but we run into such problems when the
function call stack gets 20 functions deep! Thanks in advance!

int stringManipulator(char *str)
{
/* check here to see if string is writable? */
str[0] = 'A';
str[1] = 'B';
}

int main()
{
char string_array[10] = "thisisok";

stringManipulator(string_array);
stringManipulator("thisisbad"); /* shouldn't do this */
}
 
M

Mike Wahler

Hello,

If we have c code like what's below, we will get an error because in
the stringManipulator function we attempt to modify a string literal on
the second call to the function. My question is: in the
stringManipulator function, is there any way to identify if the char*
is pointing to writable memory space to

I assume you mean 'rather than'
to a string literal?

No there is not.

If you want to ensure that the function will not
modify what the pointer points to, declare it as 'const':

int stringManipulator(const char *str)
Sure, the example is trivial, but we run into such problems when the
function call stack gets 20 functions deep!

The function call nesting level has nothing to do with
this.
int stringManipulator(char *str)
{
/* check here to see if string is writable? */
str[0] = 'A';
str[1] = 'B';
}

int main()
{
char string_array[10] = "thisisok";

stringManipulator(string_array);
stringManipulator("thisisbad"); /* shouldn't do this */
}

If the function must modify what the pointer points to,
then you can't declare it as const, and must resort to
(gasp) self-discipline in order to refrain from passing
a pointer to a non-modifiable object. There's also another
thing you should take care with: make sure that you only
pass a pointer to a string of at least a length of two
characters (plus one more for the terminator). E.g.
this will produce undefined behavior:

char a[] = "";
stringManipulator(a);


Finally, note that the language reserves to the implementation
any external names beginning with 'str' followed by a lower case
character. Your name 'stringManipulator' violates this rule.

-Mike
 
E

Emmanuel Delahaye

(e-mail address removed) a écrit :
If we have c code like what's below, we will get an error because in
the stringManipulator function we attempt to modify a string literal on
the second call to the function.

Define the string literal with the 'const' qualifier. It will ring a
bell when you pass it eo the function.

int stringManipulator(char *str)
{
/* check here to see if string is writable? */
str[0] = 'A';
str[1] = 'B';
}

int main()
{
char string_array[10] = "thisisok";

stringManipulator(string_array);
stringManipulator((char const *)"thisisbad"); /* shouldn't do this
(Awsome) */

/* or */

char const * p = "thisisbad";
stringManipulator(p);

return 0;
}

You also can activate a compiler/lint checking (like gcc's
-Wwrite-strings), at last at debug time.
 
R

Richard Heathfield

(e-mail address removed) said:
Hello,

If we have c code like what's below, we will get an error because in
the stringManipulator function we attempt to modify a string literal on
the second call to the function. My question is: in the
stringManipulator function, is there any way to identify if the char*
is pointing to writable memory space to to a string literal?

If the function doesn't write to the string you accept as a parameter, make
it const char *. Don't pass string literals as arguments except where const
char * is expected.
stringManipulator("thisisbad"); /* shouldn't do this */

So don't. The time to get this right is when you're writing the calling
code.
 
H

Herbert Rosenau

Hello,

If we have c code like what's below, we will get an error because in
the stringManipulator function we attempt to modify a string literal on
the second call to the function. My question is: in the
stringManipulator function, is there any way to identify if the char*
is pointing to writable memory space to to a string literal?

Sure, the example is trivial, but we run into such problems when the
function call stack gets 20 functions deep! Thanks in advance!

int stringManipulator(char *str)
{
/* check here to see if string is writable? */
str[0] = 'A';
str[1] = 'B';
}

int main()
{
char string_array[10] = "thisisok";

stringManipulator(string_array);

is defined
stringManipulator("thisisbad"); /* shouldn't do this */

undefined behavior.


--
Tschau/Bye
Herbert

Visit http://www.ecomstation.de the home of german eComStation
eComStation 1.2 Deutsch ist da!
 
R

Robert Gamble

Herbert said:
Hello,

If we have c code like what's below, we will get an error because in
the stringManipulator function we attempt to modify a string literal on
the second call to the function. My question is: in the
stringManipulator function, is there any way to identify if the char*
is pointing to writable memory space to to a string literal?

Sure, the example is trivial, but we run into such problems when the
function call stack gets 20 functions deep! Thanks in advance!

int stringManipulator(char *str)
{
/* check here to see if string is writable? */
str[0] = 'A';
str[1] = 'B';
}

int main()
{
char string_array[10] = "thisisok";

stringManipulator(string_array);

is defined
stringManipulator("thisisbad"); /* shouldn't do this */

undefined behavior.

If you are going to take the time to post a response, please at least
read the post you are responding to first. The OP obviously knows that
the latter is undefined, he was asking if there is any way for the
program to know at runtime that it was passed a pointer to a string
literal.

Robert Gamble
 
W

weaselboy1976

Ok, so if a compiler or lint can determine that the string is not
modifiable, then why can't I?
 
P

pemo

Ok, so if a compiler or lint can determine that the string is not
modifiable, then why can't I?

You can - if you've a brain like a C parser, and use it to parse to an
arbitrary depth.
 
P

pemo

Hello,

If we have c code like what's below, we will get an error because in
the stringManipulator function we attempt to modify a string literal on
the second call to the function. My question is: in the
stringManipulator function, is there any way to identify if the char*
is pointing to writable memory space to to a string literal?

Sure, the example is trivial, but we run into such problems when the
function call stack gets 20 functions deep! Thanks in advance!

int stringManipulator(char *str)
{
/* check here to see if string is writable? */
str[0] = 'A';
str[1] = 'B';
}

int main()
{
char string_array[10] = "thisisok";

stringManipulator(string_array);
stringManipulator("thisisbad"); /* shouldn't do this */
}

Maybe I'm reading more 'in-between the lines' that I ought to here, but, I
suspect you may have a codebase that you're porting to a platform [or that
uses a different compiler for the same platform] that allows this undefined
behaviour? And, that you'd like to run the code on your main development
platform *and* find such things? If the answer's yes, besides using lint
etc, there is a hack that you might use to get some big hints as to where
your code's got this particular problem, I won't go into it here [unless
what I say hits the nail on the head] - as it's damn awful!
 
K

Kenny McCormack

Ok, so if a compiler or lint can determine that the string is not
modifiable, then why can't I?

Short answer: *You* can, but your program can't.
Slightly longer answer: Because they have access to the source code; your
program (at runtime) does not.

Longer answer: Subject to the usual caveat of:

Not portable. Can't discuss it here. Blah, blah, blah.

You could probably figure it out yourself with a little experimentation;
figure out what sort of addresses string literals have vs. what sort of
addresses allocated space has (with all the standard caveats of: on your
platform, your compiler, etc, etc) and then write the functions to check
the value of the pointer and behave accordingly.
 
F

Flash Gordon

Ok, so if a compiler or lint can determine that the string is not
modifiable, then why can't I?

Are you a compiler or lint? If not, what makes you think you should be
able to do what they can do?

As to why a program can't determine whether a string is modifiable or
not, that is simple. The language does not provide any mechanism for
determining whether a string is modifiable or not. This allows (but does
not require) pointers to be just memory addresses rather than having to
have type information encoded in them as well.

Note that although I say that pointer can just be simple memory
addresses, they can also be something rather more complex, so don't take
what I've said as carte blanch permission to cast away warnings about
incompatible pointer types, or to pass the wrong pointer type to a
varidac function or anything like that.
 
K

Keith Thompson

Ok, so if a compiler or lint can determine that the string is not
modifiable, then why can't I?
[snip]

You could probably figure it out yourself with a little experimentation;
figure out what sort of addresses string literals have vs. what sort of
addresses allocated space has (with all the standard caveats of: on your
platform, your compiler, etc, etc) and then write the functions to check
the value of the pointer and behave accordingly.

Bad idea. The resulting function would be *extremely*
system-specific, assuming it's possible to write it consistently at
all. It would almost certainly break if you port the code to another
system. It would be likely to break on a new release of your
compiler, linker, or operating system, or when you invoke your
compiler or linker with a different set of options, or for any of a
number of other reasons.

Your time would be better spent avoiding the problem in the first
place by not writing code that depends on this.
 
K

Kenny McCormack

[email protected] (Kenny McCormack) said:
Ok, so if a compiler or lint can determine that the string is not
modifiable, then why can't I?
[snip]

You could probably figure it out yourself with a little experimentation;
figure out what sort of addresses string literals have vs. what sort of
addresses allocated space has (with all the standard caveats of: on your
platform, your compiler, etc, etc) and then write the functions to check
the value of the pointer and behave accordingly.
Bad idea. The resulting function would be *extremely* system-specific,
assuming it's possible to write it consistently at all.

So noted and stipulated.
It would almost certainly break if you port the code to another system.
It would be likely to break on a new release of your compiler, linker, or
operating system, or when you invoke your compiler or linker with
a different set of options, or for any of a number of other reasons.

I guess that, despite my best efforts, I didn't put in QUITE enough caveats
of:
(with all the standard caveats of: on your platform, your compiler, etc, etc)
to keep you quiet. Oh well, I'll be sure to do better next time.

I suppose I should have included a few "Blah, blah, blah"s as well.
Your time would be better spent avoiding the problem in the first
place by not writing code that depends on this.

I think it is pretty clear what situation the OP is in. This is a one-time
deal, and involves a large existing code base.
 

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

No members online now.

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,009
Latest member
GidgetGamb

Latest Threads

Top