Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C++11 Function That Only Accepts String Literals?

Tags:

c++

linux

gcc

c++11

I want to write a C++11 function that will only accept string literals as a parameter:

 void f(const char* s) { static_assert(s is a string literal); ... }

That is:

 f("foo"); // OK

 char c = ...;
 f(&c); // ERROR: Doesn't compile

 string s = ...;
 f(s.c_str()); // ERROR: Doesn't compile

 etc

Is there anyway to implement this? The signature of the function is open to changes, as is adding the use of macros or any other language feature.

If this is not possible what is the closest approximation? (Can user-defined literals help in anyway?)

If not is there a platform specific way in GCC 4.7 / Linux ?

like image 555
Andrew Tomazos Avatar asked Dec 05 '12 13:12

Andrew Tomazos


People also ask

How do you use string literals?

A "string literal" is a sequence of characters from the source character set enclosed in double quotation marks (" "). String literals are used to represent a sequence of characters which, taken together, form a null-terminated string. You must always prefix wide-string literals with the letter L.

What type are string literals in C++?

In C the type of a string literal is a char[]. In C++, an ordinary string literal has type 'array of n const char'. For example, The type of the string literal "Hello" is "array of 6 const char".

Are string literals read-only in C?

A string literal like "banana" or "apple" is read-only. C allows char* to point to a string literal.


2 Answers

I think the closest you are going to get is this

template<int N>
void f(const char (&str)[N]){
  ...
}

It will compile with literals and arrays but not pointers.

like image 186
Dirk Holsopple Avatar answered Sep 28 '22 04:09

Dirk Holsopple


An alternative might be to make a GCC extension to check at compile time that your particular function is only called with a literal string.

You could use MELT to extend GCC. MELT is a high-level domain specific language to extend the GCC compiler, and is very well suited for the kind of check you want.

Basically, you would add a new pass inside GCC and code that pass in MELT which would find every gimple which is a call to your function and check that the argument is indeed a literal string. The ex06 example on melt-examples should inspire you. Then subscribe to [email protected] and ask your MELT specific questions there.

Of course, this is not a foolproof approach: the function could be called indirectly thru pointers, and it could e.g. have a partial literal string, e.g. f("hello world I am here"+(i%4)) is conceptually a call with some literal string (e.g. in .rodata segment), but not in the generated code nor in the gimple.

like image 43
Basile Starynkevitch Avatar answered Sep 28 '22 04:09

Basile Starynkevitch