[英]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 中提交61e52125c935279af11b10d27060a96bff7477a4
於61e52125c935279af11b10d27060a96bff7477a4
年 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.