Search code examples
c++regexbashgccg++

GCC, G++ how to turn character too long warning into error


I am writing a huge code base for webservices backends in C++, my frontend is in Javascript, so I tend to write some frontend code and then go back to C++ code, more often then I would like, I write the following crime somewhere: container['myKey'], which usually turns into a crash somewhere, I have hot reload with cached compile, which means that if I don't catch the warning the compiler throws for the multi char string the first time it happens, I won't see it in the next compilation(because that unit will probably not recompile).

It is a very stupid error that bring random crashes to my software and that sometimes I take hours to find the culprit and fix it. For some reason the compiler Warning for multi char strings that are longer than 4 characters cannot be turned into an Error in g++ (it doesn't have a warning code, like other warnings.). Meaning I'm left with writing some kind of linter to put in my CI/CD to cause an error when a multi char literal is found.

So my idea is to write a little bash script that will check all my .cpp files for any multi char literals and return an error if it finds any.

I tried to write a regex to catch those, but I failed, I would be very happy if you, a regex magician, could help me writing a regex to catch 'things like this', but not "things 'like this'" ( a call to query("SELECT * FROM data WHERE data LIKE ('potato')") should be valid.

Thanks in advance.

Edit: Additional information: Following the solution proposed in the comments, I tried -Werror=multichar, and I found something rather curious. It works only in a few cases:

g++ -o obj/src/main.ocpp -c src/main.cpp -fno-trapping-math -Werror=multichar -O3 -std=c++17 -D_FORCE_INLINES -I./src/include -I/usr/include/mysql
src/main.cpp:52:11: error: multi-character character constant [-Werror=multichar]
   52 |   langAll['test'] = true;

Because the warning changes if there are too many characters inside the simple quotes:

g++ -o obj/src/main.ocpp -c src/main.cpp -fno-trapping-math -Werror=multichar -O3 -std=c++17 -D_FORCE_INLINES -I./src/include -I/usr/include/mysql
src/main.cpp:52:11: warning: character constant too long for its type
   52 |   langAll['testtttttt'] = true;

I found the GCC portion of code that blurts out this warning: https://github.com/gcc-mirror/gcc/blob/master/libcpp/charset.cc

if (type == CPP_UTF8CHAR)
    max_chars = 1;
  if (i > max_chars)
    {
      i = max_chars;
      cpp_error (pfile, type == CPP_UTF8CHAR ? CPP_DL_ERROR : CPP_DL_WARNING,
         "character constant too long for its type");
    }
  else if (i > 1 && CPP_OPTION (pfile, warn_multichar))
    cpp_warning (pfile, CPP_W_MULTICHAR, "multi-character character constant");

Not sure how to turn this:

CPP_DL_WARNING,"character constant too long for its type"); 

into an error though.

After talking to chatgpt it suggested: -Woverlength-strings -Werror=overlength-strings , but it also doesn't work to make that warning into an error.


Solution

  • Since no one helped, I made a solution myself to fix this issue(somewhat of a linter): https://github.com/Brasilibr/cppmultilinecharchecker It is a cpp program, you pass a folder to it as the first parameter and it will validate every file under that folder(and all folders recursively). It will check for any multi byte character with more than 4 characters, return 0 if found and 1 if all files are okay. You may use run.sh to run it in any Debian based linux, or ubuntu WSL.