-3

I've written the following program to match regular expressions in C++

#include <regex.h>
#include <iostream>

using namespace std;

/*
* Match string against the extended regular expression in
* pattern, treating errors as no match.
*
* return true for match, false for no match
*/


bool match(const char *string, char *pattern)
{
    int status; regex_t re;

    if (regcomp(&re, pattern, REG_EXTENDED|REG_NOSUB) != 0)
        return false;
    /* report error */

    status = regexec(&re, string, (size_t) 0, NULL, 0);
    regfree(&re);
    if (status != 0) {
        return false; /* report error */
    }
    return true;
}

int main()
{
    string str = "def fadi 100";
    bool matchExp = match(str.c_str(), "^[Dd][Ee][Ff][' '\t]+[A-z]+([,])?[''\t]+[0-9]+$");
    cout << (matchExp == true ? "Match": "No match") << endl;
}

The program works fine just as expected, but when I compile the code using gcc with the -Wall -Werror arguments (Linux environment), I get a very annoying warning message saying the following:

main.cpp: In function ‘int main()’:
main.cpp:33:90: warning: deprecated conversion from string constant to ‘char*’ [-Wwrite-strings]

Is there a way to force the compiler to believe that str.c_str() is the same as char * str? if so, how?

simonc
  • 41,632
  • 12
  • 85
  • 103
  • 3
    It's not the same, and your code is invalid C++11. – Cat Plus Plus Jun 26 '13 at 18:22
  • How is it annoying? It's telling you that you might have undefined behaviour. Better that than randomly have it stop working two years later and you have no clue why. – chris Jun 26 '13 at 18:24
  • why not making match function 2 parameter const char * ? – Ulterior Jun 26 '13 at 18:26
  • 3
    The compiler is not complaining about `str.c_str()`; the warning is because you're trying to assign the string literal `"^[Dd]...[0-9]+$"` to `char *pattern` parameter. Why does the pattern need to be a `char *` instead of `char const*` anyway? – Praetorian Jun 26 '13 at 18:26
  • @Praetorian I was first – Ulterior Jun 26 '13 at 18:26

4 Answers4

8

No, there isn't. That conversion was deprecated in C++03 and is illegal in C++11; don't do it.

Deprecation of that conversion comes from the fact that string literals are read-only, hence const; accessing them using a pointer to non-const char could possibly lead to modifying const objects, hence invoking undefined behavior. The warning isn't annoying; it is meant to save you from possibly crashing your application - or worse.

Also, you are wrong in reading the warning message; it isn't about c_str(), it is about passing string literal as char *.

The only way to really fix your code is to change second parameter of your match to be const char *, not char *, and copy the passed string to a new, buffer, internal to that function (why not in main()? Because with internal buffer, you have less boilerplate on the caller's side).


I'd also like to suggest totally different solution, since the question is tagged "C++": Boost.Regex.

Griwes
  • 8,805
  • 2
  • 43
  • 70
  • If the functions in `regex.h` don't specify the correct `const`-ness, there is nothing he can do about that. Telling him *"so don't use it"* is not helpful. – BlueRaja - Danny Pflughoeft Jun 26 '13 at 18:30
  • 1
    @BlueRaja-DannyPflughoeft, I believe it does take a `const char *`, so there's no excuse. Even if it didn't better to pass something that can be safely modified. – chris Jun 26 '13 at 18:53
2

Is there a way to force the compiler to believe that str.c_str() is the same as char * str?

That's actually not the issue here - you are already passing str.c_str() as a const char*.

The issue is that the second parameter is (also) a string literal, but has type char*. Try changing the second parameter to const char*.

If that still raises errors (due to the regex.h functions not specifying the correct const-ness), you're going to have to do something like this in main() or match():

char pattern[] = "^[Dd][Ee]...etc";
bool matchExp = match(str.c_str(), pattern);

See here for the reason why.

Community
  • 1
  • 1
BlueRaja - Danny Pflughoeft
  • 84,206
  • 33
  • 197
  • 283
1

The problem is that a string literal should be only assigned to a pointer of a const char, so you need to change match to take a char const* pattern (which should be possible when you pass a string literal)

bennofs
  • 11,873
  • 1
  • 38
  • 62
1

Make 2 parameter of function match const char *, warning is because of it

Ulterior
  • 2,786
  • 3
  • 30
  • 58