8

I have a function, which takes a character array and its size:

void store_string (const char *p, size_t size); // 'p' & 'size' stored in map

The function is wrapped by a macro as:

#define STORE_STRING(X) store_string(X, sizeof(X))

My problem is that I want to somehow prohibit or inform user that only string literal should be passed to this function. Because, if any pointer or local array are stored inside the map then they might go out of scope and create a havoc!

Is there any compile-time way (preferred) or at least run-time way to do it?

unwind
  • 391,730
  • 64
  • 469
  • 606
  • 5
    No, there isn't. And that would be really bad design. Store std::strings instead. –  Apr 28 '11 at 13:18
  • @unapersson, my requirement is that to store a char* only for some reasons; as code is having lots of string literals – HiddenAngel Apr 28 '11 at 13:20
  • @HiddenAngel My code normally contains lots of string literals too, but I've never had problems about copying them. What actual issues are you experiencing? –  Apr 28 '11 at 13:23
  • @unapersson, if we already have allocated strings in form of literals, then why should I copy them ? Somebody has given a correct answer however, which is working for me now. – HiddenAngel Apr 28 '11 at 13:27
  • @HiddenAngal: If someone has given a correct answer, perhaps you should **accept** it so its author gets rewarded ? – ereOn Apr 28 '11 at 13:38
  • @ereOne, sure. I have already accepted that iammilind has given correct answer; that just above your comment. thanks. – HiddenAngel Apr 28 '11 at 13:47
  • 1
    You have not accepted it. On SO, "accept" means click the check mark to turn it green. This rewards the person who gave the answer and makes sure it stays at the top of the answers for others to see. – R.. GitHub STOP HELPING ICE Apr 28 '11 at 14:10

3 Answers3

26

You can know it compile time, by simply changing your macro to:

#define STORE_STRING(X) store_string("" X, sizeof(X))

Usage:

char a[] = "abcd", *p;
STORE_STRING(a); // error
STORE_STRING(p); // error
STORE_STRING("abcd"); // ok
iammilind
  • 68,093
  • 33
  • 169
  • 336
0

This does not work, sizeof(char *) returns the size of the pointer not the memory allocated or string size.

strlen(x) returns the size of a string by looking for the '\0'.

Hogan
  • 69,564
  • 10
  • 76
  • 117
0

If you need/want a non-macro solution there is one template trick that can help. You can have a function signature that looks like this:

template<int len>
void store_string( char const (&str)[len] ) { store_string_internal( str,len); }

template<int len>
void store_string( char (&str)[len] ) { static_assert( false ); }

The first form accepts strings literals and calls the target function. The second form prevents non-const character arrays from being passed. And yeah, don't offer a char const* version.

This doesn't guarantee that the string is a string literal, but the one syntax needed to bypass it is extremely rare (I've never used it).

Otherwise the macro version from iammilind is nice.

edA-qa mort-ora-y
  • 30,295
  • 39
  • 137
  • 267
  • qa, thx. However, in the template solution, the function will pass for `const char x[]` also; which is NOT a string literal. Now that array might be declared locally in a function. In fact, I had given this solution earlier in similar question, and I had got few down votes. . – iammilind Apr 28 '11 at 14:10
  • I know, it's not foolproof, but the use of `const char x[]` other than string literal is pretty uncommon. When is the last time you'd done this `const char[] = "A String"`? Besides, I'd be willing to bet that is still compiled as a pointer to a constant memory location (probably sufficient for your needs)? – edA-qa mort-ora-y Apr 28 '11 at 14:22
  • yes, in a way you are right. Many compiler consider `const char x[]` equivalent to compile time string literal. In fact, I had debated the same at that time; but there was a down vote chain which haunted my answer. :) . Then I came up with the same answer I gave above, but it went unnoticed. I was lucky this time. See here: http://stackoverflow.com/questions/5691232/can-i-determine-if-an-argument-is-string-literal/5726814#5726814 – iammilind Apr 29 '11 at 05:51
  • People love arguing nonsense sometimes. I mean if we're really pedantic I don't even know if the standard guarantees a string literal can't go out of scope. But a reasonably compiler would never do that. No form is 100% safe, the determined programmer can bypass both the function and the macro. However, they both help protect the code from slight mishaps, which is a big help. – edA-qa mort-ora-y Apr 29 '11 at 06:26