0

How to find out if passed argument in the function was string or char(not sure how to call it correctly) literal?

My function(incorrect):

void check(const char* str)
{
    // some code here
}

I want to call it with:

int main()
{
    check("Hello"); // Correct call

    std::string hello = "Hello";
    check(hello.c_str()); // Must be compile error here
}
  • 9
    You can't. A given `const char *` is exactly identical to every other `const char *`. This is an XY problem. What is the real problem you're trying to solve. No, not the one you're asking, but the one you think the answer is what you're asking about. – Sam Varshavchik Nov 16 '16 at 13:43
  • 3
    `// Must be compile error here` Huh? Why actually? – πάντα ῥεῖ Nov 16 '16 at 13:47
  • A platform-dependent way would be to compare the pointer against information you get from the linker describing the extent of the `text` section. But since this is likely a XY problem, there's little point detailing that unless you can demonstrate that this 'requirement' is actually necessary. – Toby Speight Nov 16 '16 at 18:26

2 Answers2

7

For both solutions, I'm renaming your check function to check_impl and wrapping it.

This can't be done with the compiler alone, but we can come close:

template <std::size_t N>
void check(char const (&str)[N]) {
    return check_impl(str);
}

This only takes in references to const char arrays, which are not all that common. But you can still pass a named array instead of a string literal.

Enter the preprocessor:

#define check(str) check_impl("" str)

This very simple macro just adds an empty literal right against your parameter. If the parameter is another string literal, the compiler will then merge them, otherwise this will be a syntax error.

Quentin
  • 62,093
  • 7
  • 131
  • 191
2

This thing might or might not do what you want:

constexpr const char* check(const char* c) {
    return c;   
}

Usage:

int main() {
    constexpr auto result = check("test");
    constexpr auto result2 = check(std::string("test").c_str()); // error
}

The produced error message is:

main.cpp:11:61: error: call to non-constexpr function 'const _CharT* std::__cxx11::basic_string<_CharT, _Traits, _Alloc>::c_str() const [with _CharT = char; _Traits = std::char_traits<char>; _Alloc = std::allocator<char>]'
     constexpr auto result2 = check(std::string("test").c_str());
                                    ~~~~~~~~~~~~~~~~~~~~~~~~~^~

The way it works isn't checking the literal directly; rather than that, it checks whether the const char* value can be obtained at compile time, which, again, could be more meaningful, but not exactly what you want.

Bartek Banachewicz
  • 38,596
  • 7
  • 91
  • 135