C++ 编译器会在局部变量隐藏另一个变量时发出警告。例如https://godbolt.org/g/TYYf8F
然而,当派生类的成员隐藏基类的成员时,没有一个主要的 C++ 编译器发出警告:
class A
{
int _memberVar = 2;
public:
virtual int memberVar()
{
return _memberVar;
}
};
class B : public A
{
int _memberVar = 3;
};
int main()
{
A* pB = new B();
return pB->memberVar(); // returns 2
}
Run Code Online (Sandbox Code Playgroud)
背后有原因吗?
最近想用from_charsc++17。查看http://en.cppreference.com/w/cpp/utility/from_chars并在此页面上找到了该代码:
#include <iostream>
#include <charconv>
#include <array>
int main()
{
std::array<char, 10> str{"42"};
int result;
std::from_chars(str.data(), str.data()+str.size(), result);
std::cout << result;
}
Run Code Online (Sandbox Code Playgroud)
不能被任何编译器编译。我在页面http://en.cppreference.com/w/cpp/utility/from_chars和 godbolt 上尝试使用不同的编译器,但它们都返回了相同的错误:
<source>:2:10: fatal error: 'charconv' file not found
#include <charconv>
^~~~~~~~~~
1 error generated.
Compiler returned: 1
Run Code Online (Sandbox Code Playgroud)
有人可以帮我解决这个问题吗?
(我尝试了 clang 6.0、gcc 7.3 和 msvc 19,但它们都返回了未找到“charconv”的错误)
我在 Ubuntu 17.10 上。我安装了 NVIDIA 的 CUDA 9.1 SDK。
这是我尝试过的:
~/GrinGoldMiner/src/Cudacka$ clang++-5.0 -Wl,--cuda-path=/usr/local/cuda-9.1 kernel.cu
clang: error: cannot find libdevice for sm_20. Provide path to different CUDA installation via --cuda-path, or pass -nocudalib to build without linking with libdevice.
clang: error: cannot find CUDA installation. Provide its path via --cuda-path, or pass -nocudainc to build without CUDA includes.
clang: error: cannot find CUDA installation. Provide its path via --cuda-path, or pass -nocudainc to build without CUDA includes.
Run Code Online (Sandbox Code Playgroud)
显然这是行不通的。似乎链接器标志没有通过。我怎样才能正确地传递它们?
所以用这个人为的代码 - 用 clang 编译工作得很好,但是当使用 ccache 时会出现额外的警告/错误 - 我认为 ccache 应该透明地传递这些。这是来自 epel 存储库的 CentOS 6 上的 ccache 3.1.6 - 升级不是一种选择,因为这是生产环境。
#include <byteswap.h>
int main()
{
int i = 42;
auto j = bswap_32(i);
(void)j;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
因此,带有未使用的包含路径的示例 1 没有给出错误:
clang++ -Wno-c++98-compat -Wall -Werror -std=c++17 -I/usr/local/include -c ccache.cpp
Run Code Online (Sandbox Code Playgroud)
但是使用 ccache 我得到:
ccache clang++ -Wno-c++98-compat -Wall -Werror -std=c++17 -I/usr/include/xmlib -c ccache.cpp
clang-5.0: error: argument unused during compilation: '-I /usr/include/xmlib' [-Werror,-Wunused-command-line-argument]
Run Code Online (Sandbox Code Playgroud)
没有额外包含的示例 2 工作得很好:
clang++ -Wno-c++98-compat -Wall -Werror -std=c++17 -c ccache.cpp
Run Code Online (Sandbox Code Playgroud)
并使用 …
我有一些 Clang 正在为其生成警告的代码。这是从实际代码中简化的,但精神是一样的。this_t在本地类中用于实例化其他一些模板类。
template<class T>
struct value_holder
{
T value;
};
template<class T>
int get_value()
{
struct value_t
{
using this_t = value_t;
// ^ here
static value_holder<this_t> val()
{
return value_holder<this_t>();
}
operator int()
{ return 0; }
};
return value_t::val().value;
}
int main(int argc, char** argv) {
return get_value<void>();
}
Run Code Online (Sandbox Code Playgroud)
使用 编译时-std=c++1z -Wall,Clang 会警告unused type alias:
main.cpp:14:15: warning: unused type alias 'this_t' [-Wunused-local-typedef]
using this_t = value_t;
^
1 warning generated.
Run Code Online (Sandbox Code Playgroud)
您可以在 …
Clang 有许多消毒剂,可以在运行时检查可疑行为。不幸的是,它们不能同时启用。
不能在同一程序中组合多个
-fsanitize=address,-fsanitize=thread, 和-fsanitize=memory检查器。
更糟糕的是,这三个中的每一个似乎都非常有用,不能省略。AddressSanitizer 检查内存错误,ThreadSanitizer 检查竞争条件,MemorySanitizer 检查未初始化的读取。 我担心所有这些事情!
显然,如果我对虫子的位置有预感,我可以据此选择消毒剂。但如果我不这样做呢?更进一步,如果我想使用消毒剂作为预防工具而不是诊断工具来指出我什至不知道的错误怎么办?
换句话说,鉴于我没有特别寻找任何东西,默认情况下我应该使用哪种消毒剂进行编译? 我是不是只需要编译和测试整个程序三遍,每个消毒剂一次?
通过这个简单的例子,我得到了一个编译错误:
#include <unordered_map>
int main() {
std::unordered_map<int, int> a, b;
a.merge(b);
}
Run Code Online (Sandbox Code Playgroud)
错误:
$ clang++ -std=c++17 merge.cpp
merge.cpp:5:4: error: no member named 'merge' in 'std::__1::unordered_map<int, int, std::__1::hash<int>, std::__1::equal_to<int>, std::__1::allocator<std::__1::pair<const int, int> > >'
a.merge(b);
~ ^
1 error generated.
Run Code Online (Sandbox Code Playgroud)
版本:
$ clang++ --version
clang version 6.0.0 (tags/RELEASE_600/final)
Target: x86_64-apple-darwin17.5.0
Thread model: posix
InstalledDir: /usr/local/opt/llvm/bin
Run Code Online (Sandbox Code Playgroud)
根据 cppreference,从 C++17 开始这应该是合法的。GCC 7 很乐意编译它。
假设我的 C++ 符合标准并且我不依赖第三方库,那么在将 makefile 中的“g++”替换为“clang++”时遇到的常见陷阱是什么?像不兼容的编译器选项、选项顺序的不同要求、其他一些限制等。
假设我在编译时已知 N 个不同的整数值,V_1 到 V_N。考虑以下结构:
const int x = foo();
switch(x) {
case V_1: { /* commands for V_1 which don't change x */ } break;
case V_2: { /* commands for V_1 which don't change x */ } break;
/* ... */
case V_N: { /* commands for V_1 which don't change x */ } break;
}
Run Code Online (Sandbox Code Playgroud)
相对
const int x = foo();
if (x == V_1) { /* commands for V_1 which don't change x */ }
else …Run Code Online (Sandbox Code Playgroud) 根据关于复制赋值运算符的 C++ 参考:
如果以下任何一项为真,则类 T 的默认复制赋值运算符被定义为已删除
T 有一个非类类型(或其数组)的非静态数据成员,它是 const ...
我希望创建一个案例,其中我有一个 const 类类型的数据成员和一个未定义为已删除的默认复制赋值运算符。在这样做时,我发现了 clang 和 gcc 之间的差异。考虑以下代码:
struct B {
void operator=(const B&) const {}
};
struct A {
const B b{};
A& operator=(const A&) = default;
};
int main() {
A a1{}, a2{};
a1 = a2; //only works with clang
B b1{}, b2{};
b1 = b2; //works in both
}
Run Code Online (Sandbox Code Playgroud)
当我编译它时,g++ -std=c++14我收到以下错误:
In member function ‘A& A::operator=(const A&)’:
error: non-static const member ‘const B A::b’, …Run Code Online (Sandbox Code Playgroud) clang++ ×10
c++ ×7
clang ×4
g++ ×4
c++17 ×2
gcc ×2
visual-c++ ×2
c++14 ×1
ccache ×1
cuda ×1
llvm-clang ×1
sanitizer ×1
type-alias ×1