尝试将char *添加到int时触发编译器错误?

伊斯特万

C ++编译器愉快地编译了此代码,没有警告:

int ival = 8;
const char *strval = "x";
const char *badresult = ival + strval;

在这里,我们将char *指针值(strval)添加到int值(ival)并将结果存储在char *指针(badresult)中。当然,badresult的内容将是全部垃圾,当应用程序尝试在其他地方使用badresult时,该应用程序可能会在此行或稍后崩溃问题是在现实生活中容易犯这样的错误。我在我的代码中发现的代码如下所示:

message += port + "\n";

(其中message是使用其运算符+ =函数处理结果的字符串类型; port是int且\ n显然是const char指针)。

有什么方法可以禁用这种行为并在编译时触发错误?

我看不到将char *添加到int的任何正常用例,并且我想找到一种解决方案,以防止在我的大型代码库中出现这种错误。使用类时,我们可以创建私有运算符并使用explicit关键字禁用不需要的转换/广播,但是现在我们正在谈论基本类型(char *和int)。

一种解决方案是使用clang,因为clang具有用于启用警告的标志。但是我不能使用clang,所以我正在寻找一种触发编译器错误的解决方案(某种操作员重载或使用某些定义进行修饰以防止此类构造或任何其他想法)。

巴西尔·斯塔林凯维奇

有什么方法可以禁用这种行为并在编译时触发错误?

一般而言,因为您的代码与以下合法代码非常相似:

 int ival = 3;
 const char *strval = "abcd";
 const char *goodresult = ival + strval;

这里goodresult所指向的最后一个字母dstrval

顺便说一句,在Linux上,已知getpid(2)返回一个正整数。因此,您可以想象:

 int ival = (getpid()>=0)?3:1000;
 const char *strval = "abcd";
 const char *goodresult = ival + strval;

从道德上讲,它与前面的示例相同(因此我们人类知道,ival始终为3)。但教学,编译器getpid()不返回负值在实践中是棘手的(返回类型pid_tgetpid一些签名整数,并已被签名是由可用叉(2) 这可能给-1)。您可以想象更多奇怪的例子!

您需要编译时检测缓冲区溢出(或更一般而言,未定义的行为),并且通常与停止问题等效(这是无法解决的问题)。因此,一般来说这是不可能的。

当然,可以声称聪明的编译器可以针对您的特定情况发出警告,但随后担心哪些情况应该对警告有用。

您可以尝试使用某些静态源程序分析工具,例如Clang静态分析器Frama-C(具有其最新的Frama-C ++变体),或者某些昂贵的专有工具,例如Coverity等。这些工具不能静态地检测所有错误,并且比优化编译器花费更多的时间来执行。

您可以(例如)编写自己的GCC插件来检测此类错误(这意味着要开发自己的静态源代码分析器)。您将花费数月的时间编写它。您确定值得付出努力吗?

但是我不能用c

为什么?您可以在开发过程中(而非用于生产)请求使用clang静态分析器(或其他方法)的许可。如果您的经理拒绝,则将成为管理问题,而不是技术问题。


我看不到将char *添加到int的任何正常用例

您需要更多的想象力。想像

puts("non-empty" + (isempty(x)?4:0));

好的,这不是很易读的代码,但这是合法的。在上个世纪,当内存成本很高时,一些人曾经使用这种方式进行编码。

今天您可能会编码

if (isempty(x))
    puts("empty");
else
    puts("non-empty")

而可爱的事情是,一个聪明的编译器可能会将后者优化为等效于前者(根据as-if规则)。

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

将AFNetwork添加到Xcode的编译器错误

将@SuppressWarnings(“ unchecked”)泛型添加到单行会产生eclipse编译器错误

将库添加到C编译器

将编译器开关添加到Eclipse CDT内置编译器设置生成中?

尝试将 char[] 存储到 char* 时出现问题

当我尝试将项目添加到列表时,Flutter 编辑器显示错误

将TypeScript编译器推断的类型添加到原始TS源代码中

如何将makefile中的编译器命令行添加到源代码

将Gradle依赖关系添加到IntelliJ编译器类路径

CMake:将条件编译器标志添加到Visual Studio项目中

如何将Swift编译器添加到目标C项目

如何将全局CXX编译器标志添加到yocto构建

使用VisualD将-unittest参数添加到编译器

编译器找不到头文件,是否将目录添加到PATH?

将MinGW编译器添加到QT 5.6.0 Windows

如何将多个编译器参数添加到meson.build

是将零添加到空指针的未定义行为,编译器错误或其他错误的失败测试吗?

将* void项目添加到* void数组中时,编译器如何知道要在内存中使用多少字节?

如何将4.0参考程序集添加到构建服务器(以便编译器找到它们)?

尝试将对象添加到 Typescript 数组时出现编译错误

编译错误:尝试将数组分配给数组时,从不兼容的类型“char”分配给“int”

是否可以将Visual C ++ v120编译器工具集添加到Visual Studio 2015?

尝试创建菜单时出现编译器错误

尝试从struct打印时出现编译器错误

C预处理器-在编译时将元素添加到结构

错误:每次尝试将包添加到meteorjs时,ENOTDIR错误

将char *添加到char **

当我尝试将昨天的日期添加到 GET 参数(NASA APOD API)时出现“注释参数必须是编译时常量”错误

尝试使用random_device,mt19937和uniform_int_distribution时出现许多编译器错误