c - 用显式转换替换隐式转换有任何副作用吗?

标签 c casting implicit-conversion

显式转换比隐式转换更好吗?

例如,我有一个枚举...

/*This enum represents the various encryption types for wifi. For wifi capable devices, a bitwise & result of all supported encryption types should be returned.*/
typedef enum wifi_encryptionType {
    /*Unknown encryption - default value, and for if wifi standard is ever expanded.*/
    WIFIENCTYPE_UNKNOWN = 0,

    /*No encryption - an open network.*/
    WIFIENCTYPE_NONE = 1,

    /*WEP encryption - all widths.*/
    WIFIENCTYPE_WEP = 2,

    /*WPA 1 with a preshared key using Temporal Key Integrity Protocol.*/
    WIFIENCTYPE_WPA_PSK_TKIP = 4,

    /*WPA 1 with a preshared key using Advanced Encryption Standard via CCMP. */
    WIFIENCTYPE_WPA_PSK_AES = 8,

    /*WPA 2 with a preshared key using Temporal Key Integrity Protocol.*/
    WIFIENCTYPE_WPA2_PSK_TKIP = 16,

    /*WPA 2 with a preshared key using Advanced Encryption Standard via CCMP.*/
    WIFIENCTYPE_WPA2_PSK_AES = 32

} wifi_encryptionType;

我在结构中使用它。

typedef struct {
    char ssid[32];
    wifi_encryptionType encryption;
    wifi_mode mode;
} WifiNetwork;

然后我使用该结构字段的值作为函数调用的参数...

read_uint8(readBuffer, &network.encryption);
//read_uint8 takes a struct pointer containing some buffer info, and a uint8_t pointer.

我收到警告。

warning: passing argument 2 of 'read_uint8' from incompatible pointer type
expected 'uint8_t *' but argument is of type 'enum wifi_encryptionType *'

我明白警告的意思了。 “请注意,读取 uint8_t 并将其放入 wifi_encryptionType 字段可能会在其中放置未映射到您已声明的任何值的值。”

类型转换现在是隐式完成的。

让它显式转换更好吗?显式转换是否有任何好处或任何缺点?

最佳答案

这种情况下的警告不仅仅是编译器挑剔。这可能会破坏。

原因是 enum 类型的大小可能与 uint8_t 不同。 C11 标准仅保证(第 6.7.2.2 节)

Each enumerated type shall be compatible with char, a signed integer type, or an unsigned integer type.

如果你不走运并且 enum 具有与例如相同的表示形式int,那么您将有效地传递一个指向 int 的初始字节的指针。在大端系统上,该字节不会与 int 具有相同的值,即使该值适合。

另一个问题(虽然在这里可能不适用)是严格的别名,这意味着允许编译器假设相同的数据不作为两种不同的类型访问。一个示例是让 int*float* 指向同一位置,通过 int* 写入该位置,然后通过 float* 从中读取。严格的别名规则允许代码优化,因为编译器可以假设通过 int* 写入不会弄乱 float* 指向的值(这样它会例如,必须重新加载到寄存器中)。

严格别名在这里可能不适用的原因是 uint8_t 在实践中几乎可以肯定是 unsigned char,编译器对此异常(exception)。 char*(或unsigned char*)可用于访问任何类型对象的内存。如果不允许这样做,那么就没有任何安全的方法来根据需要进行“原始”字节操作,例如memcpy().

关于c - 用显式转换替换隐式转换有任何副作用吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29300002/

相关文章:

c++ - Matlab 代码生成 : Does not support anonymous functions

c# - 将类型对象动态转换为类型(某些类)

c++ - 避免动态转换的架构策略

swift - `catMaybe as? Animal` 和 `catMaybe as Animal?` 之间的区别

Scala:同一范围内的类型类、默认和自定义隐式转换

Scala 隐式转换问题

c++ - 如何修复隐式转换的 C++ 警告?

c - 如何通过微处理器/微 Controller 同时检测两个或多个按钮按下(GPIO)?

c - 如何规避 Windows 通用 CRT header 对 vcruntime.h 的依赖

c - 为什么这个程序不停止接受输入?