这是代码:
int main()
{
char* a = "abc"; // Should be 'const char*', but no warnings whatsoever on VS
a[1] = 'e'; // No warnings on VS either
std::cout<< a << " " << a[1];
return 0;
}
使用GCC版本6.2.0:
>g++ -O2 -o Test Test.cpp
Test.cpp: In function ‘int main()’:
Test.cpp:5:15: warning: ISO C++ forbids converting a string constant to ‘char*’ [-Wwrite-strings]
char* a = "abc";
^~~~~
>./Test
Segmentation fault (core dumped)
使用VS 2015.3编译:
>cl /EHsc /W4 /WX /O2 Main.cpp
Microsoft (R) C/C++ Optimizing Compiler Version 19.00.24215.1 for x86
Copyright (C) Microsoft Corporation. All rights reserved.
Main.cpp
Microsoft (R) Incremental Linker Version 14.00.24215.1
Copyright (C) Microsoft Corporation. All rights reserved.
/out:Main.exe
Main.obj
>Main.exe
abc e
HUH?^
没有/O2
的编译也不会发出警告,但在运行时崩溃。
这是一个VS编译器错误还是我缺少某些内容?
我认为这可以称为错误。使用a[1] = 'e';
,您只会更改读取内存。弦字母不会被预期修改。这实际上是一种不确定的行为。为什么VS编译器没有发出警告,例如GCC?好吧,每个程序(编译器也是一个程序)都可以更好。在这种特殊情况下,非常古老的编译器代码有效,因为这不是最近的C 功能(例如T&&
引用)。旧代码可能不会发出最佳错误。
还有许多其他编写不良代码的方法。不幸的是,在C/C 中,这相对容易。我们在这里。
有许多静态代码检查器和消毒剂(例如:Codesonar)。通常它们不是免费的。他们遇到了很多问题,但并非全部。