enforcing type safety when casting char* to bool i

2019-06-21 00:04发布

Following code compiles fine without any warnings (with default options to g++). Is there a flag that we can use to ask g++ to emit warnings in such cases?

void foo(bool v) {
}

void bar() {
  foo("test");
}

2条回答
一纸荒年 Trace。
2楼-- · 2019-06-21 00:32

I like to try clang -Weverything and pick the warnings that pop out:

void foo(bool) {}

void bar() {
  foo("test");
}

void baz() {
    foo(nullptr);    
}

int main() {}

main.cpp:5:7: warning: implicit conversion turns string literal into bool: 'const char [5]' to 'bool' [-Wstring-conversion] foo("test");

main.cpp:8:9: warning: implicit conversion of nullptr constant to 'bool' [-Wnull-conversion] foo(nullptr);

Unfortunately, neither -Wstring-conversion nor -Wnull-conversion is supported by g++. You could try and submit feature request / bug report to gcc.

查看更多
贼婆χ
3楼-- · 2019-06-21 00:40

If I really wanted to prevent such a function being passed a pointer, I would do this in C++11;

 void foo(bool);
 template<class T> void foo(T *) = delete;

 void bar()
 {
     foo("Hello");
 }

which will trigger a compiler error.

Before C++11 (not everyone can update for various reasons) a technique is;

 void foo(bool);
 template<class T> void foo(T *);   // note no definition

 void bar()
 {
     foo("Hello");
 }

and then have the definition of foo(bool) somewhere (in one and only one compilation unit within your build). For most toolchains that use a traditional compiler and linker (which is most toolchains in practice, including most installations of g++) the linker error is caused by foo<char const>(char const*) not being defined. The precise wording of the error is linker dependent.

Note that the errors can be deliberately circumvented by a developer. But such techniques will stop accidental usage.

If you want to allow any pointer except a char const * being passed, simply declare void foo(const char *) as above and don't declare the template.

查看更多
登录 后发表回答