以下最小代码在g ++上编译,但不会在clang ++上编译:
template<class T>
T operator*(float a, const T& b)
{
return b * a;
}
struct A{
A operator*(float b) const
{
A a;
return a;
}
};
int main()
{
A a;
2.0f * a;
}
Run Code Online (Sandbox Code Playgroud)
这是我得到的错误:
$ clang++ test.cpp
test.cpp:2:3: error: overloaded 'operator*' must have at least one parameter of
class or enumeration type
T operator*(float a, const T& b)
^
test.cpp:4:11: note: in instantiation of function template specialization
'operator*<float>' requested here
return b * a; …Run Code Online (Sandbox Code Playgroud) 以下程序的正确行为是什么?
// example.cpp
#include <iostream>
#include <memory>
struct Foo {
void Bar() const {
std::cout << "Foo::Bar()" << std::endl;
}
};
std::shared_ptr<Foo> MakeFoo() {
return std::make_shared<Foo>();
}
int main() {
auto p { MakeFoo() };
p->Bar();
}
Run Code Online (Sandbox Code Playgroud)
当我在Linux RHEL 6.6工作站中编译它时,我得到以下结果:
$ g++ -v
gcc version 5.1.0 (GCC)
$ g++ example.cpp -std=c++14 -Wall -Wextra -pedantic
$ ./a.out
Foo::Bar()
Run Code Online (Sandbox Code Playgroud)
但
$ clang++ -v
clang version 3.6.0 (trunk 217965)
$ clang++ example.cpp -std=c++14 -Wall -Wextra -pedantic
example.cpp:16:4: error: member reference type 'std::initializer_list<std::shared_ptr<Foo> >' …Run Code Online (Sandbox Code Playgroud) 在clang/llvm 3.6.2中,以下代码在编译时导致编译错误std=c++11:
template <typename T=void>
class bar
{
public:
struct foo
{
int array[10];
};
int baz()
{
return sizeof(foo::array);
}
};
int main(void)
{
bar<> b;
return b.baz();
}
Run Code Online (Sandbox Code Playgroud)
命令行调用:
$ clang++ -std=c++11 nonstatic.cpp -o nonstatic
nonstatic.cpp:12:28: error: invalid use of non-static data member 'array'
return sizeof(foo::array);
~~~~~^~~~~
nonstatic.cpp:20:14: note: in instantiation of member function
'bar<void>::baz' requested here
return b.baz();
Run Code Online (Sandbox Code Playgroud)
如果我改为bar不再是模板,就像在
class bar
{
public:
struct foo
{
int array[10];
};
int baz()
{
return …Run Code Online (Sandbox Code Playgroud) 这是一个说明问题的简化版本:
struct Foo {
Foo() = default;
template <std::size_t N>
Foo(const char(&)[N]) {}
};
template <std::size_t N>
auto foo(const char (&arr)[N]) -> Foo
{
return arr;
}
auto main() -> int
{
foo("Stack Overflow");
}
Run Code Online (Sandbox Code Playgroud)
虽然数组引用参数传递给数组引用参数,但g ++似乎已经衰减arr了const char *.它给出了这个错误:
在实例化中
Foo foo(const char (&)[N]) [with long unsigned int N = 4ul]:错误:无法转换
(const char*)arr从const char*到FooRun Code Online (Sandbox Code Playgroud)return arr; ^
虽然clang ++表现出我的期望并编译代码.
使用以下任何修改,代码在gcc上编译良好:
return {arr};
return Foo(arr);
return (Foo)arr;
return static_cast<Foo>(arr);
Run Code Online (Sandbox Code Playgroud)
这是一个gcc bug吗? …
我有一个librandom.so库和一个mainexectuable,编译如下:
$ clang++ -o main main.o -lrandom -L. -Wl,-rpath,"\$ORIGIN"
Run Code Online (Sandbox Code Playgroud)
它们都在同一目录中.由于main它$ORIGIN在其中rpath,它工作正常 - ./main返回没有错误.
现在,我设置main与运行setuid为root:
$ sudo chown root main
$ sudo chmod a+s main
$ ./main
Run Code Online (Sandbox Code Playgroud)
我预计main会失败,因为$ORIGIN没有在setuid应用程序中扩展.令人惊讶的是,它有效.
如果我运行main从另一个目录,但是,它不会如预期失败:
$ cd /tmp
$ /path/to/main
/path/to/main: error while loading shared libraries: librandom.so: cannot open shared object file: No such file or directory
Run Code Online (Sandbox Code Playgroud)
当我main从包含目录运行时为什么它可以工作?
对于以下 C++14 代码,为什么 g++ 生成的代码new A[1]{x}似乎调用了复制构造函数两次?
#include <iostream>
using namespace std;
class A {
public:
A() { cout << "default ctor" << endl; }
A(const A& o) { cout << "copy ctor" << endl; }
~A() { cout << "dtor" << endl; }
};
int main()
{
A x;
cout << "=========" << endl;
A* y = new A[1]{x};
cout << "=========" << endl;
delete[] y;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
编译和输出:
$ g++ -fno-elide-constructors -std=c++14 test.cpp && ./a.out
default …Run Code Online (Sandbox Code Playgroud) 请考虑以下代码:
class A {
public:
int i;
A() {}
};
class B {
public:
A a;
int i;
};
int main() {
B* p = new B {};
std::cout << p->i << " " << p->a.i << "\n";
}
Run Code Online (Sandbox Code Playgroud)
在clang ++中用-std = c ++ 11编译,p->i结果为零,但p->a.i没有.只要它的类没有用户提供的构造函数,整个对象是否应该归零?
编辑:由于评论中有一些广泛的讨论,我认为最好从标准中添加一些摘录:
对值初始化类型的对象
T意味着:
- 如果
T是具有用户提供的构造函数(12.1)的(可能是cv限定的)类类型(第9节),则调用T的默认构造函数(如果T没有可访问的默认构造函数,则初始化是错误的);- 如果
T是没有用户提供的构造函数的(可能是cv限定的)非联合类类型,则该对象是零初始化的,如果T隐式声明的默认构造函数是非平凡的,则调用该构造函数.- 如果
T是数组类型,则每个元素都是值初始化的;- 否则,该对象被零初始化.
零初始化T类型的对象或引用意味着:
- 如果
T是标量类型(3.9),则将对象设置为值0(零),作为整数常量表达式,转换为T;- 如果
T是(可能是cv限定的)非联合类类型,则每个非静态数据成员和每个基类子对象都是零初始化的,并且填充初始化为零位;- if
T …
我正在编译我的程序,clang++ -fsanitize=memory -fsanitize-memory-track-origins -fno-omit-frame-pointer -g -O0当我运行它时,输出是:
matiu@matiu-laptop:~/projects/json++11/build$ ./tests
.......==10534== WARNING: MemorySanitizer: use-of-uninitialized-value
#0 0x7fe7602d4a51 (/home/matiu/projects/json++11/build/tests+0x106a51)
#1 0x7fe7602dfca6 (/home/matiu/projects/json++11/build/tests+0x111ca6)
...
#31 0x7fe75edbaec4 (/lib/x86_64-linux-gnu/libc.so.6+0x21ec4)
#32 0x7fe7602808dc (/home/matiu/projects/json++11/build/tests+0xb28dc)
Uninitialized value was created by a heap allocation
#0 0x7fe76026e7b3 (/home/matiu/projects/json++11/build/tests+0xa07b3)
#1 0x7fe7602ee7da (/home/matiu/projects/json++11/build/tests+0x1207da)
...
#18 0x7fe7602c1c4c (/home/matiu/projects/json++11/build/tests+0xf3c4c)
#19 0x7fe7602873fa (/home/matiu/projects/json++11/build/tests+0xb93fa)
SUMMARY: MemorySanitizer: use-of-uninitialized-value ??:0 ??
Exiting
Run Code Online (Sandbox Code Playgroud)
如何让它显示像美丽的例子中的行号:http://clang.llvm.org/docs/MemorySanitizer.html
我怀疑它可能是不可能的,因为我的pragram是一群巨大的嵌套lambda:https://github.com/matiu2/json--11/blob/master/tests.cpp
我注意到一个有趣的行为与clang(我使用3.6.0),我没有在文档或其他任何地方找到任何关于它的参考.这是一个小例子:
int main(){
int a;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
我编译它,clang++ -Wall -W -Werror -Wno-error=unused-variable main.cpp我有预期的警告:
main.cpp:2:9: warning: unused variable 'a' [-Wunused-variable]
int a;
1 warning generated.
Run Code Online (Sandbox Code Playgroud)
现在,让我们试试吧 clang++ -Werror -Wno-error=unused-variable -Wall -W main.cpp
main.cpp:2:9: error: unused variable 'a' [-Werror,-Wunused-variable]
int a;
1 error generated.
Run Code Online (Sandbox Code Playgroud)
我错过了什么吗?这是预期的吗?对于这一点,gcc编译两行.
这是MCVE:
#include <iostream>
#include <regex>
std::string s()
{
return "test";
}
int main()
{
static const std::regex regex(R"(\w)");
std::smatch smatch;
if (std::regex_search(s(), smatch, regex)) {
std::cout << smatch[0] << std::endl;
}
return 0;
}
Run Code Online (Sandbox Code Playgroud)
编译很好:
$ clang ++ -std = c ++ 11 main.cpp
但不是:
$ clang ++ -std = c ++ 14 main.cpp
后一种情况下的错误消息(使用-std = c ++ 14):
main.cpp:14:9: error: call to deleted function 'regex_search'
if (std::regex_search(s(), smatch, regex)) {
^~~~~~~~~~~~~~~~~
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/regex:5998:1: note:
candidate function [with _ST = std::__1::char_traits<char>, …Run Code Online (Sandbox Code Playgroud)