有这个代码:
class A;
template <class T>
void fun() {
A a;
}
class A {
public:
A() { }
};
int main() {
fun<int>();
return 0;
}
Run Code Online (Sandbox Code Playgroud)
g ++ 4.5和g ++ 4.7编译时没有错误.但是clang ++ 3.2(trunk)给出了这个错误:
main.cpp:5:6: error: variable has incomplete type 'A'
A a;
^
main.cpp:1:7: note: forward declaration of 'A'
class A;
^
Run Code Online (Sandbox Code Playgroud)
根据C++标准,哪个编译器是正确的?
使用--save-temps选项保存临时文件时,gcc/clang会将临时文件输出到与输入文件相同的目录中.是否有选项指示gcc将文件输出到其他目录.
要么
不使用--save-temps选项时,临时文件是在默认目录(即$ TMPDIR,如/ tmp)中创建的,但是一旦创建了目标文件,它们就会被删除.有没有办法指示编译器保留这些文件而不是删除它们(我认为唯一的选择是--save-temps,它有上述问题)
我有以下示例代码,简化为必需的,编译与gcc 6.1,gcc 7.0 head和Visual Studio 2015/2017RC,但没有任何clang版本.
#include <iostream>
#include <tuple>
using namespace std;
namespace outer {
namespace test {
template <typename A, typename B, typename...C>
auto bar_(A&&, B&&, C&&... c) {
return std::make_tuple(c._p...);
}
}
template <typename A, typename B, typename...C>
auto bar(A a, B b, C&&... c) {
return test::bar_(std::move(a), std::move(b), std::forward<C>(c)...);
}
template<typename T>
class foo
{
template <typename A, typename B, typename...C>
friend auto test::bar_(A&&, B&&, C&&... c);
int _p;
public:
foo(int f) : _p(f) {}
}; …Run Code Online (Sandbox Code Playgroud) 我刚刚在clang和gcc之间遇到了一个奇怪的区别,我想编译看起来类似于以下内容的代码:
namespace n1 {
template <class T1, class T2>
struct MyTemplate {
struct Inner {};
};
}
using namespace n1;
namespace n2 {
using MyClass = MyTemplate<int, int>;
}
namespace n1 {
using n2::MyClass;
template<> struct MyClass::Inner {
int member;
};
MyClass::Inner inner{0};
}
Run Code Online (Sandbox Code Playgroud)
Clang愉快地编写了这个:
$ clang++ -std=c++11 -c -o alias_specialization.o alias_specialization.cc
Run Code Online (Sandbox Code Playgroud)
但是gcc会抛出以下错误:
$ g++ -std=c++11 -c -o alias_specialization.o alias_specialization.cc
alias_specialization:15:30: error: declaration of ‘struct n1::MyTemplate<int, int>::Inner’ in namespace ‘n1’ which does not enclose ‘using MyClass = struct n1::MyTemplate<int, int>’ …Run Code Online (Sandbox Code Playgroud) 尝试打印第一个命令行参数时:
std::cout << argv[0] << std::endl;
Run Code Online (Sandbox Code Playgroud)
clang-tidy发出警告:
警告:[cppcoreguidelines-pro-bounds-pointer-arithmetic]中的'不使用指针运算'
有argv没有使用指针算法的替代方法来使用值?是不是char**通过任何明智的方法访问必须使用指针算术?
我欣赏有一些专门的函数来处理命令行参数,但它们似乎太重了,不能简单地打印一个参数.
我正在编写c++,使用clang编译器和构建cmake.
c++ pointer-arithmetic command-line-arguments clang-static-analyzer clang++
给出以下源代码:
#include <memory>
#include <typeinfo>
struct Base {
virtual ~Base();
};
struct Derived : Base { };
int main() {
std::unique_ptr<Base> ptr_foo = std::make_unique<Derived>();
typeid(*ptr_foo).name();
return 0;
}
Run Code Online (Sandbox Code Playgroud)
并编译它:
clang++ -std=c++14 -Wall -Wextra -Werror -Wpedantic -g -o test test.cpp
环境设置:
linux x86_64
clang version 5.0.0
Run Code Online (Sandbox Code Playgroud)
由于警告(注释-Werror)它不编译:
error: expression with side effects will be evaluated
despite being used as an operand to 'typeid'
[-Werror,-Wpotentially-evaluated-expression]
typeid(*ptr_foo).name();
Run Code Online (Sandbox Code Playgroud)
(请注意:海湾合作委员会并未声称存在这种潜在问题)
题
有没有办法获得有关a指向的类型的信息unique_ptr而不产生那种警告?
注意:我不是在谈论禁用-Wpotentially-evaluated-expression或避免-Werror.
我无法在仿生海狸上使用 clang-6.0 构建简单的 hello world 应用程序,构建命令失败并显示以下错误。
clang++-6.0 -std=c++17 -stdlib=libc++ hello.cc -o hello
/usr/bin/ld: cannot find -lc++abi
clang: error: linker command failed with exit code 1 (use -v to see invocation)
Run Code Online (Sandbox Code Playgroud)
这个 c++abi 库是什么,我在哪里可以找到它??请指教。
在没有初始化主要参考模板的情况下在C++ 14中声明参考模板是否合法,只要它从未实例化?
template<class T>
const T& ref;
template<>
auto ref<int> = 1;
auto x = ref<int>;
Run Code Online (Sandbox Code Playgroud)
这会在GCC和Clang上产生不同的结果:
$ g++ -std=c++14 -c ref.cpp
$
$ clang -std=c++14 -c ref.cpp
ref.cpp:2:10: error: declaration of reference variable 'ref' requires an
initializer
const T& ref;
^~~
1 error generated.
Run Code Online (Sandbox Code Playgroud)
没有必要初始化主要参考模板,因为在实例化之前,它是模板,而不是参考.
我发现我可以这样做:
template<class T>
const T& ref = "Meaningless initialization with any value of any type";
template<>
auto ref<int> = 1;
auto x = ref<int>;
Run Code Online (Sandbox Code Playgroud)
因为显然GCC和Clang都接受但忽略了参考模板初始化器RHS,只要它是一个有效的表达式并且主参考模板永远不会被实例化.任何类型的任何表达式都满足Clang的初始化要求.
只要主参考模板从未实例化,GCC就不需要初始化程序.这似乎是"在精神上"的正确行为,因为在实际实例化参考模板之前,它不应该需要初始化器.
标准在参考模板上不是100%明确.这是我在变量模板实例化上找不到的东西:
14.7.1
除非已显式实例化或显式专门化变量模板特化,否则在使用特化时隐式实例化变量模板特化.
...
实现不应隐式实例化......不需要实例化的变量模板.
14.7.2
除了内联函数,从其初始值或返回值(7.1.6.4)推导出的类型的声明
const …
当我只是检查哪些链接被授予外部局部变量时,
我发现编译器之间的一些不同行为
例如,如果我测试了下面的代码,
正如您在评论中看到的那样,变量vars 有不同的链接
// foo.cpp
int var = 10; // external linkage
// main.cpp
#include <iostream>
static int var = 100; // internal linkage
int main() {
extern int var; // internal linkage
std::cout << var << std::endl;
{
extern int var; // g++: external linkage , clang++: internal linkage
std::cout << var << std::endl;
{
extern int var; // g++: external linkage , clang++: internal linkage
std::cout << var << std::endl;
}
}
}
Run Code Online (Sandbox Code Playgroud)
结果是 …
有人可以解释为什么两个编译器都在第二个示例中抛出错误而只有 gcc 在第一个示例中抛出错误吗?它是否与static_cast作为 xvalue的结果有关?
int& example1 = reinterpret_cast<int&>(static_cast<int&&>(10));
//(gcc 10.2) error: invalid cast of an rvalue expression of type 'int' to type 'int&'
//(clang 11.0.0) no errors
int& example2 = reinterpret_cast<int&>(10);
//(gcc 10.2) error: invalid cast of an rvalue expression of type 'int' to type 'int&'
//(clang 11.0.0) error: reinterpret_cast from rvalue to reference type 'int &'
Run Code Online (Sandbox Code Playgroud)
我也不确定,但我认为第一个例子是格式良好的,因为根据标准,xvalue 是 glvalue 的一种类型,对吧?并且标准的这个[expr.reinterpret.cast]/11部分说我应该能够将 T1 泛左值转换为“对 T2 的引用”类型,在这种情况下,T1 与 T2 的类型相同。