warning: dereferencing type-punned pointer will break strict-aliasing rules [-Wstrict-aliasing]

3 篇文章 0 订阅
下面的文章详细介绍了这个warning的来源和解决方法。也可以关闭优化,当然关闭优化并不是最终解决方法。

down vote accepted

First off, let's examine why you get the aliasing violation warnings.

Aliasing rules simply say that you can only access an object through its own type, its signed / unsigned variant type, or through a character type (charsigned charunsigned char).

C says violating aliasing rules invokes undefined behavior (so don't!).

In this line of your program:

unsigned int received_size = ntohl (*((unsigned int*)dcc->incoming_buf));

although the elements of the incoming_buf array are of type char, you are accessing them as unsigned int. Indeed the result of the dereference operator in the expression *((unsigned int*)dcc->incoming_buf) is of unsigned int type.

This is a violation of the aliasing rules, because you only have the right to access elements of incoming_buf array through (see rules summary above!) charsigned char or unsigned char.

Notice you have exactly the same aliasing issue in your second culprit:

*((unsigned int*)dcc->outgoing_buf) = htonl (dcc->file_confirm_offset);

You access the char elements of outgoing_buf through unsigned int, so it's an aliasing violation.

Proposed solution

To fix your issue, you could try to have the elements of your arrays directly defined in the type you want to access:

unsigned int incoming_buf[LIBIRC_DCC_BUFFER_SIZE / sizeof (unsigned int)];
unsigned int outgoing_buf[LIBIRC_DCC_BUFFER_SIZE / sizeof (unsigned int)];

(By the way the width of unsigned int is implementation defined, so you should consider using uint32_t if your program assumes unsigned int is 32-bit).

This way you could store unsigned int objects in your array without violating the aliasing rules by accessing the element through the type char, like this:

*((char *) outgoing_buf) =  expr_of_type_char;

or

char_lvalue = *((char *) incoming_buf);
down vote accepted

First off, let's examine why you get the aliasing violation warnings.

Aliasing rules simply say that you can only access an object through its own type, its signed / unsigned variant type, or through a character type (charsigned charunsigned char).

C says violating aliasing rules invokes undefined behavior (so don't!).

In this line of your program:

unsigned int received_size = ntohl (*((unsigned int*)dcc->incoming_buf));

although the elements of the incoming_buf array are of type char, you are accessing them as unsigned int. Indeed the result of the dereference operator in the expression *((unsigned int*)dcc->incoming_buf) is of unsigned int type.

This is a violation of the aliasing rules, because you only have the right to access elements of incoming_buf array through (see rules summary above!) charsigned char or unsigned char.

Notice you have exactly the same aliasing issue in your second culprit:

*((unsigned int*)dcc->outgoing_buf) = htonl (dcc->file_confirm_offset);

You access the char elements of outgoing_buf through unsigned int, so it's an aliasing violation.

Proposed solution

To fix your issue, you could try to have the elements of your arrays directly defined in the type you want to access:

unsigned int incoming_buf[LIBIRC_DCC_BUFFER_SIZE / sizeof (unsigned int)];
unsigned int outgoing_buf[LIBIRC_DCC_BUFFER_SIZE / sizeof (unsigned int)];

(By the way the width of unsigned int is implementation defined, so you should consider using uint32_t if your program assumes unsigned int is 32-bit).

This way you could store unsigned int objects in your array without violating the aliasing rules by accessing the element through the type char, like this:

*((char *) outgoing_buf) =  expr_of_type_char;

or

char_lvalue = *((char *) incoming_buf);
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: dereferencing type-punned pointer是指对一个类型转换后的指针进行解引用操作。这种操作可能会导致未定义的行为,因为不同类型的指针可能具有不同的内存布局和对齐方式,解引用操作可能会访问到错误的内存位置,导致程序崩溃或产生不可预测的结果。因此,应该避免使用这种类型的指针操作。 ### 回答2: dereferencing type-punned pointer(解引用类型转换指针) 首先需要了解的是类型转换指针,它是一个指针,它可以将一个变量解释为不同类型的变量。例如,一个int型指针可以转换为一个char型指针,它可以让程序员通过不同类型查看同一块内存区域,但是这个过程是非常危险的,尤其是在解引用指针时,很容易引发问题。 当我们使用一个指针解引用时,我们希望得到的是一个合法的内存地址,即指向有效的对象的指针。但是如果我们使用一个类型转换指针,则不一定能够保证指针指向的内存区域是有效的。这种情况可能导致非法的内存访问、程序崩溃,并可能导致安全漏洞。例如,以下代码使用了一个类型转换指针: ``` int a = 10; float b = *(float*)&a; ``` 这个代码段将一个整数a的地址解释为一个浮点数b的地址,并通过解引用类型转换指针来获取浮点数的值。如果a的内存区域不足以容纳一个浮点数,或者已经被释放了,那么这个代码就会引起问题。 解决这个问题的方法是使用正确的类型来解引用指针,或者使用内存操作函数来完成转换。例如,在上面的例子中,我们可以使用以下代码来完成类型转换: ``` int a = 10; float b; memcpy(&b, &a, sizeof(float)); ``` 这个代码使用了memcpy函数将一个整数a的地址复制到一个float类型的变量b中。这种方法可以保证我们不会出现类型转换指针导致的问题。 ### 回答3: dereferencing type-punned poin是指对通过类型转换得到指针的解引用操作。在C/C++中,类型转换是一种常见的操作,有时候我们需要将一个指针“重新解释”为另外一个指针类型,通过这种方式访问不同类型的数据。但是,这种做法实际上是非法的,可能会引起严重的后果。 具体来说,dereferencing type-punned poin可能会导致以下几个问题: 1.非法内存访问。由于类型转换后,指针所指向的数据类型发生了变化,新的数据类型可能会导致访问非法内存。 2.未定义的行为。C/C++标准中有很多规则限制了指针类型转换的行为,如果不遵守这些规则,可能会导致未定义的行为。 3.平台依赖性。某些类型转换可能会涉及平台依赖性,例如对指针进行位操作,这种做法可能会依赖于底层硬件的字节序等因素。 因此,避免dereferencing type-punned poin非常重要。如果确实需要进行类型转换,建议使用标准库中提供的转换函数,而不是手动进行位操作等操作。另外,在使用指针类型转换时,也要充分了解C/C++标准中的规则,以避免不必要的安全问题。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值