簡體   English   中英

gcc -std=c++20 編譯器標志 -Wrestrict 不理解。 警告是否合理?

[英]gcc -std=c++20 compiler flag -Wrestrict not understood. Is the warning justified?

以下代碼可以在 gcc 11.3.0 下正常編譯。

#include <string>

std::string homeName( const std::string& home, std::string surl )
{
   if ( surl.find( home ) == 0 )
   {
      surl.replace( 0, home.size(), "~" ); // shorten url by replacing $HOME with "~"
   }

   return surl;
}

也就是說,如果字符串 surl 以 home 的值開頭,則將頭部替換為波浪號“~”。 但是,當我切換到 gcc 12.2.1 時,出現了一個我不明白的警告(-Wrestrict,包含在 -Wall 中)。 警告是針對帶有替換命令的行。 下面給出了完整的消息(像往常一樣幾乎不可讀),但首先是一些試驗的結果:我將完整的編譯器命令修剪為基本部分。

gcc11  -Wrestrict -O2 -std=c++20 -c file.cpp        # Ok, with/without optimisations. 
gcc12  -Wrestrict -O2 -std=c++20 -c file.cpp        # warning, but not with std=c++17
gcc12  -Wrestrict =O1 -std=c++20 -c file.cpp        # Ok

從手冊:
-Wrestrict:當限制限定參數(或 C++ 中的 __restrict 限定參數)引用的 object 被另一個參數別名時,或者當此類對象之間的副本重疊時發出警告。 但是,我真的不明白這如何適用於上面的代碼。 有人可以解釋發生了什么嗎?

這是一些示例 output:

[655] build> g++ --version
g++ (SUSE Linux) 12.2.1 20220830 [revision e927d1cf141f221c5a32574bde0913307e140984]
Copyright (C) 2022 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

[655] build> g++ -Wrestrict -O2 -std=c++20 -c file.cpp
In file included from /usr/include/c++/12/string:40,
                 from file.cpp:1:
In static member function ‘static constexpr std::char_traits<char>::char_type* std::char_traits<char>::copy(char_type*, const char_type*, std::size_t)’,
    inlined from ‘static constexpr void std::__cxx11::basic_string<_CharT, _Traits, _Alloc>::_S_copy(_CharT*, const _CharT*, size_type) [with _CharT = char; _Traits = std::char_traits<char>; _Alloc = std::allocator<char>]’ at /usr/include/c++/12/bits/basic_string.h:423:21,
    inlined from ‘static constexpr void std::__cxx11::basic_string<_CharT, _Traits, _Alloc>::_S_copy(_CharT*, const _CharT*, size_type) [with _CharT = char; _Traits = std::char_traits<char>; _Alloc = std::allocator<char>]’ at /usr/include/c++/12/bits/basic_string.h:418:7,
    inlined from ‘constexpr std::__cxx11::basic_string<_CharT, _Traits, _Allocator>& std::__cxx11::basic_string<_CharT, _Traits, _Alloc>::_M_replace(size_type, size_type, const _CharT*, size_type) [with _CharT = char; _Traits = std::char_traits<char>; _Alloc = std::allocator<char>]’ at /usr/include/c++/12/bits/basic_string.tcc:532:22,
    inlined from ‘constexpr std::__cxx11::basic_string<_CharT, _Traits, _Alloc>& std::__cxx11::basic_string<_CharT, _Traits, _Alloc>::replace(size_type, size_type, const _CharT*, size_type) [with _CharT = char; _Traits = std::char_traits<char>; _Alloc = std::allocator<char>]’ at /usr/include/c++/12/bits/basic_string.h:2171:19,
    inlined from ‘constexpr std::__cxx11::basic_string<_CharT, _Traits, _Alloc>& std::__cxx11::basic_string<_CharT, _Traits, _Alloc>::replace(size_type, size_type, const _CharT*) [with _CharT = char; _Traits = std::char_traits<char>; _Alloc = std::allocator<char>]’ at /usr/include/c++/12/bits/basic_string.h:2196:22,
    inlined from ‘std::string homeName(const std::string&, std::string)’ at file.cpp:7:19:
/usr/include/c++/12/bits/char_traits.h:431:56: warning: ‘void* __builtin_memcpy(void*, const void*, long unsigned int)’ accessing 9223372036854775810 or more bytes at offsets [2, 9223372036854775807] and 1 may overlap up to 9223372036854775813 bytes at offset -3 [-Wrestrict]
  431 |         return static_cast<char_type*>(__builtin_memcpy(__s1, __s2, __n));
      |                                        ~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~
[656] build> 

發生的事情是一個明顯的 gcc 錯誤。 顯示的代碼沒有任何問題(除了下面提到的不相關的錯誤)。 切換到 gcc 12 后,我自己的代碼開始彈出相同的診斷信息。

我懷疑這個特定案例是bug 100366的另一個實例,它首次出現在 gcc 11 中,但由於額外的內部編譯器優化被絆倒,它似乎在 gcc 12 中變得更加普遍。

警告似乎是無害的。 但這很煩人。 到目前為止,使用我自己的代碼,我已經成功地進行了調整,使其 go 消失了。 在這種情況下,如果我將其重寫為:

   if ( surl.find( home ) == 0 )
   {
       surl="~" + surl.substr(home.size());
   }

也就是說,如果字符串 surl 以 home 的值開頭,則用波浪號替換頭部,

如果是這種情況,那么顯示的代碼會稍微偏離目標。 因為如果我的home目錄是/home/sam ,這/home/samv/foo替換為~v/foo ,這顯然是錯誤的(您的原始版本也有同樣的錯誤)。

因此,除了修復編譯器警告之外,您還應該認真思考這里應該有什么正確的邏輯。 乍一看,它並不像看起來那么簡單。 文件名不僅僅是隨機字符串。 他們有結構,並且對他們有一點組織。

暫無
暫無

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

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