簡體   English   中英

gcc size_t 和 sizeof 算術轉換為 int

[英]gcc size_t and sizeof arithmetic conversion to int

我決定在啟用 -Wsign-conversion 的情況下測試編譯一個項目,看看會出現什么警告,並遇到一些似乎不正確的東西,其中 gcc 的行為與 clang 不同。 有人可以告訴我哪個是正確的嗎?

我有一個接受size_t參數的函數:

void func(size_t) {}

其他一些結構

struct Test {};

和調用代碼

int i = some_initialiser();
func(sizeof(Test) + static_cast<size_t>(i));

因此,從我的理解, sizeof回報size_t ,和類型的兩個變量之間的算術size_t應返回size_t ,所以應該不會在這里比我的其他任何轉換static_cast ,但GCC給我的警告

 warning: conversion to ‘long unsigned int’ from ‘int’ may change the sign of the result [-Wsign-conversion]

Clang 不會在這里發出警告,但如果我按預期刪除函數調用中的static_cast ,則會發出警告。

這是 gcc 中的一個已知錯誤,已在 9.3.0 及更高版本中修復。

警告是有效的(編譯器可以警告任何他們喜歡的東西),但 gcc 的行為與其自己的文檔相矛盾。 這個問題有一個現有的錯誤報告(見下文)。

這是一個更簡單的測試用例,說明了這個問題:

#include <cstddef>
int main() {
    int i = 42;
    size_t s0 = sizeof (int) + (size_t)i;
    size_t s1 = sizeof (int) + static_cast<size_t>(i);
}

當我使用 gcc 9.1.0 在我的系統上編譯它時,我得到:

$ g++ -Wsign-conversion -c c.cpp
c.cpp: In function ‘int main()’:
c.cpp:4:32: warning: conversion to ‘long unsigned int’ from ‘int’ may change the sign of the result [-Wsign-conversion]
    4 |     size_t s0 = sizeof (int) + (size_t)i;
      |                                ^~~~~~~~~
c.cpp:5:32: warning: conversion to ‘long unsigned int’ from ‘int’ may change the sign of the result [-Wsign-conversion]
    5 |     size_t s1 = sizeof (int) + static_cast<size_t>(i);
      |                                ^~~~~~~~~~~~~~~~~~~~~~
$ 

請注意,C 樣式轉換和static_cast都會出現警告。

確實,轉換可能會改變結果的符號(將負int轉換為size_t產生正結果),但 gcc 的-Wsign-conversion文檔說:

'-Wsign-conversion'
     Warn for implicit conversions that may change the sign of an
     integer value, like assigning a signed integer expression to an
     unsigned integer variable.  An explicit cast silences the warning.
     In C, this option is enabled also by '-Wconversion'.

在這種情況下,顯式強制轉換不會使警告靜音。

這個錯誤已經被報告了:
錯誤 87519 - -Wsign-conversion -Wconversion 顯式轉換無法使警告靜音

修復是在 gcc git repo 中提交61e52125c935279af11b10d27060a96bff7477a461e52125c935279af11b10d27060a96bff7477a4年 8 月 8 日提交。

警告是正確的。

如果i有一個負值,鑄造就會有問題。 您的函數應該返回一個無符號值(例如 unsigned int)。

來自 GCC 文檔 - https://gcc.gnu.org/onlinedocs/gcc/Warning-Options.html

對於 C++,還警告混淆用戶定義轉換的重載解析; 和從不使用類型轉換運算符的轉換:轉換為void 、相同類型、基類或對它們的引用。 除非顯式啟用-Wsign-conversion否則 C++ 中默認禁用有關有符號和無符號整數之間轉換的警告。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM