views:

81

answers:

4

Is there a way to check (assert) at compile time wether a const char* contains spaces or not?

Something like:

const char* cstr1 = "ok";
const char* cstr2 = "very bad";

check( cstr1 ); //OK
check( cstr2 ); //Fail to compile

The type is the same, but it may be possible to define some tricky template metaprogramming tecnique to do it.

Point is, all the info required is fixed at compile time.

This problem should be related to the "From const char variable to type" problem, which I think can be solved by compile-time hashing via metaprogramming tecniques.

Thank you in advance for your help.

+2  A: 

The problem is that you don't know cstr at compile time.

int i = function_call();
const char* cstr = NULL;

if(i > 0)
{
   cstr = "hello";
}
else
{
   cstr = "ciaooo";
}

Consider the example above. The compiler does not now what value const char* cstr will assume until runtime.

Basically I would say you can't make such check at compile time.

Note that though being declared as const this does not mean the variable cstr is constant. Note that the pointer type is const. You have to read it like this: (const char)* cstr. This means you cannot perform such operations cstr[0] = 's';

A pure constant would be declared like this:

const char * const CONSTANT = "test";

A new assignment would fail at compile time. Even if you used this approach, I don't think there is a possibility to evaluate the content of the constant at compile time.

Simon
This makes sense, thank you for pointing this out!
KRao
+2  A: 

I don't think so. If that was possible, how would the compiler manage to check this at compile time?

const char* cstr3 = some_dynamic_function();

check( cstr3 );
T.E.D.
+4  A: 

You can't use ordinary strings since their characters cannot be accessed by templates, but you can use MPL strings:

#include <boost/mpl/char.hpp>
#include <boost/mpl/string.hpp>
#include <boost/mpl/contains.hpp>
#include <boost/utility/enable_if.hpp>

typedef boost::mpl::char_<' '> space;
typedef boost::mpl::string<'o', 'k'> cstr1;
typedef boost::mpl::string<'v', 'e', 'r', 'y', ' ', 'b', 'a', 'd'> cstr2;

boost::disable_if< boost::mpl::contains<cstr1, space> >::type check();
// boost::disable_if< boost::mpl::contains<cstr2, space> >::type check();

The second line fails to compile.

Philipp
Those `disable_if` are the wrong tool for the job, at the very least it conveys the wrong intent - just use e.g. `BOOST_STATIC_ASSERT` to get simple compile time errors.
Georg Fritzsche
This is the closest to what I wanted to achieve, thanks!
KRao
+1  A: 

Write a script that checks the string literals that you care about, and fails if any of them have spaces.

Run this script during your build process.

Make the success of your build process dependent upon the success of the script.

Bill