下面的代码用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中),我不明白。警告是针对具有replace命令的行的。完整的消息(像往常一样几乎不可读)给出了下面的内容,但首先是一些试验的结果:我将完整的编译器命令裁剪到基本部分。
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++中,一个__限制-限定参数)被另一个参数别名时,或者当这些对象之间的副本重叠时,警告。但是,我并不真正理解这如何适用于上面的代码。有人能解释一下发生了什么事吗?
下面是一些示例输出:
[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> 发布于 2022-12-04 15:34:05
正在发生的是一个明显的gcc错误。显示的代码没有什么问题(除了下面提到的不相关的bug)。在切换到gcc 12之后,同样的诊断从我自己的代码中开始出现。
我怀疑这个具体的例子是bug 100366的另一个例子,它最初出现在gcc 11中,但由于受到额外的内部编译器优化的影响,这种情况在gcc 12中似乎变得更加普遍。
这个警告似乎是无害的。但这很烦人。到目前为止,使用我自己的代码,我已经成功地提出了一些使其消失的调整。在这种情况下,如果我将其重写为:
if ( surl.find( home ) == 0 )
{
surl="~" + surl.substr(home.size());
}也就是说,如果字符串surl以home的值开头,用一个倾斜的值替换头部,
如果是这样的话,那么显示的代码就会略为漏掉标记。因为如果我的home目录是/home/sam,这将用~v/foo代替/home/samv/foo,这显然是错误的(您的原始版本也有相同的错误)。
因此,除了修复编译器警告之外,您还应该仔细考虑正确的逻辑应该是什么。乍一看,它并不像看上去那么简单。文件名不仅仅是随机字符串。他们有结构,也有一点组织。
https://stackoverflow.com/questions/74677951
复制相似问题