问题是如何制作clang关于哪些循环(或代码的其他部分)已被矢量化的打印信息.GCC有一个命令行开关命名-ftree-vectorizer-verbose=6为这样做,但我找不到类似的东西clang.是否clang支持此或我唯一的选择是在拆卸偷看?
我发现gcc(4.9.2)和clang(3.5.0)之间的行为有所不同,令我感到惊讶.
当我尝试unsigned int从一个std::istringstream带有负值的初始值(在示例中为"-15")中提供一个时,我得到了
fail()clang ++ 出错(带位)signed(-15)用gcc ++ 初始化我准备了以下示例程序.
#include <sstream>
#include <iostream>
int main ()
{
std::istringstream iss("-15");
unsigned int ui;
iss >> ui;
std::cout << "ui[" << ui << "] signed(ui)[" << signed(ui)
<< "] flags[" << iss.fail() << iss.good() << iss.bad()
<< iss.eof() << "]\n";
return 0;
}
Run Code Online (Sandbox Code Playgroud)
使用clang ++,我获得以下输出
ui[0] signed(ui)[0] flags[1001]
Run Code Online (Sandbox Code Playgroud)
使用g ++,我获得以下输出
ui[4294967281] signed(ui)[-15] flags[0001]
Run Code Online (Sandbox Code Playgroud)
我有两个问题.
首先是显而易见的:谁是对的?clang ++,g ++还是一个未定义的行为?
第二个是:我如何强制gcc ++的行为类似于clang ++,从一个以减号开头的字符串中提取无符号值时会出错?
谢谢,抱歉我的英语不好.
编辑2016.04.03
我意识到这不是g ++和clang ++之间的区别,而是libstd …
我正在尝试调试我正在编写的C++程序,但是当我在LLDB中运行并停止程序时,它只显示汇编程序,而不是原始源代码.例如,崩溃之后我正在尝试调试:
Process 86122 stopped
* thread #13: tid = 0x142181, 0x0000000100006ec1 debug_build`game::update() + 10961, stop reason = EXC_BAD_ACCESS (code=EXC_I386_GPFLT)
frame #0: 0x0000000100006ec1 debug_build`game::update() + 10961
debug_build`game::update:
-> 0x100006ec1 <+10961>: movq (%rdx), %rdx
0x100006ec4 <+10964>: movq %rax, -0xb28(%rbp)
0x100006ecb <+10971>: movq -0x1130(%rbp), %rax
0x100006ed2 <+10978>: movq 0x8(%rax), %rsi
Run Code Online (Sandbox Code Playgroud)
我正在编译-O0 -g.通过Xcode(我在OSX上)或从命令行运行调试器时,我看到同样的事情.
我还需要做些什么才能让源代码显示在LLDB中?
补充说明
以下是典型构建命令的示例:
clang++ -std=c++1y -stdlib=libc++ -fexceptions -I/usr/local/include -c -O2 -Wall -ferror-limit=5 -g -O0 -ftrapv lib/format.cpp -o format.o
Run Code Online (Sandbox Code Playgroud)
之前-O2是因为那是我正在使用的默认值,但我相信后者-O0会覆盖它,对吧?
我试过的
我用一个简单的'hello world'程序使用相同的构建设置重新创建了这个问题.
经过一些搜索,我试着运行dsymutil main.o …
我正在传递一个带有init捕获循环计数器的lambda,如下所示:
#include <iostream>
auto sq(int c, int x) { return c * x * x; }
struct S {
template<class Fun>
void for_each(Fun fun) const {
for (auto i = 1; i < 4; ++i) {
fun(i);
}
}
};
int main()
{
S s;
auto sum = 0;
s.for_each([&, i = 2](auto c) mutable {
sum += sq(c, i++);
});
std::cout << sum; // 70 = 1 * 4 + 2 * 9 + 3 * 16
}
Run Code Online (Sandbox Code Playgroud)
对于g …
前段时间,GCC> = 5和Clang> = 4编译器改变了他们的版本号的语义,因此任何非bugfix版本的主版本号都会增加.
Apple在ABI兼容性或任何其他范围方面是否遵循任何带有clang编译器的版本模式?我想知道apple-clang 9.0ABI是否兼容9.1等等.
我最近开始使用C++ 14而不是C++ 11来使我的C++代码库现代化.
在用C++ 14 替换了一次std::unique_ptr.reset(new ...)使用后std::make_unique,我意识到我的测试套件(由大约30个C++测试程序组成)运行速度慢了约50%.
旧C++ 11代码(快速):
class Foo
{
public:
Foo(size_t size)
{
array.reset(new char[size]);
}
private:
std::unique_ptr<char[]> array;
};
Run Code Online (Sandbox Code Playgroud)
新的C++ 14代码(慢):
class Foo
{
public:
Foo(size_t size)
{
array = std::make_unique<char[]>(size);
}
private:
std::unique_ptr<char[]> array;
};
Run Code Online (Sandbox Code Playgroud)
使用C++ 14代码时,GCC和Clang都运行得慢得多std::make_unique.当我使用valgrind测试两个版本时,它报告C++ 11和C++ 14代码使用相同数量的分配和相同数量的已分配内存,并且没有内存泄漏.
当我查看上面生成的测试程序的程序集时,我怀疑C++ 14版本std::make_unique在使用memset分配后使用重置内存.C++ 11版本没有这样做:
C++ 11程序集(GCC 7.4,x64)
main:
sub rsp, 8
movsx rdi, edi
call operator new[](unsigned long)
mov rdi, rax
call operator delete[](void*)
xor eax, eax
add rsp, …Run Code Online (Sandbox Code Playgroud) Clang有各种消毒剂,可以在运行时开启以解决问题.
但是,有一些消毒剂我不能一起使用.这是为什么?
clang++-3.9 -std=c++1z -g -fsanitize=memory -fsanitize=address -o main main.cpp 1
clang: error: invalid argument '-fsanitize=address' not allowed with '-fsanitize=memory'
Run Code Online (Sandbox Code Playgroud)
这不是什么大问题,但是当我运行单元测试时,它需要的时间比它应该的长,因为我为相同的测试创建了多个二进制文件,并分别运行它们.
clang++-3.9 -std=c++1z -g -fsanitize=address -o test1 test.cpp
clang++-3.9 -std=c++1z -g -fsanitize=memory -fsanitize=undefined -o test2 test.cpp
Run Code Online (Sandbox Code Playgroud) 我只是在学习如何编码.
我使用visual studio 14在Windows 10系统上安装了clang版本5.
我创建了一个hello world cpp文件来测试它是否正常工作.
示例代码
#include <iostream>
using namespace std;
int main()
{
cout << "Hello World!\n";
int rip{1};
int dal{4};
int kane = rip + dal;
cout << kane;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
命令
clang++ -o .\bin\testing.exe test.cpp
Run Code Online (Sandbox Code Playgroud)
Clang确实编译了,我得到一个可执行文件,它按预期运行.但我确实收到了这条消息.
test-3e53b3.o : warning LNK4217: locally defined symbol ___std_terminate imported in function "int `public: __thiscall std::basic_ostream<char,struct std::char_traits<char> >::sentry::~sentry(void)'::`1'::dtor$5" (?dtor$5@?0???1sentry@?$basic_ostream@DU?$char_traits@D@std@@@std@@QAE@XZ@4HA)
test-3e53b3.o : warning LNK4217: locally defined symbol __CxxThrowException@8 imported in function "public: void __thiscall std::ios_base::clear(int,bool)" (?clear@ios_base@std@@QAEXH_N@Z)
Run Code Online (Sandbox Code Playgroud)
我在网上搜索过,可以找到类似的问题,但它们不一样.
我意识到这对你们来说可能很简单,但我不知道我使用过各种IDES和GCC,而且此代码之前没有产生过这个警告.
我基本上有一个依赖于非类型模板参数的类.我定义了一个转换,所以非类型模板参数的对象N可以转换为另一个M.我有一个可以重现这种情况的最小例子:
template<auto Integral>
class Test{
public:
typedef decltype(Integral) value_type;
static constexpr value_type N = Integral;
constexpr Test (const value_type& x = 0);
template<auto Integral2>
constexpr explicit operator Test<Integral2>() const;
private:
value_type n;
};
template<auto Integral>
constexpr Test<Integral>::Test (const value_type& x){
if (x < 0){
n = N - (-x)%N;
}
else{
n = x%N;
}
}
template<auto Integral> template<auto Integral2>
constexpr Test<Integral>::operator Test<Integral2>() const{
return Test<Integral2>(n%(Test<Integral2>::N));
}
Run Code Online (Sandbox Code Playgroud)
我正在使用GCC 7.2.0和Clang 5.0.0在Ubuntu 16.04 LTS中使用标志进行编译-O2 -std=c++17.
问题是我一直在使用g …
有没有办法为typedef声明的(周围)类型本身构建一个类型声明,而不说明类型的名称?
例:
class X
{
public:
typedef <fill in magic here> MyType;
//...
};
Run Code Online (Sandbox Code Playgroud)
背景:这看起来很傻.我需要这个,因为我使用宏构建了数据类的编译时反射.因此,在数据类的声明中插入了一个宏,需要处理它所插入的类型.到目前为止,我找到了MSVC和g ++的工作解决方案,它们都依赖于我认为在实现中存在的缺陷.因此他们可能无法使用更新的版本.Clang不会"吃掉"这些解决方案.
我当前的MSVC解决方案定义了一个方法,然后仅通过它的名称获取它的地址,并调用一个"返回"它的类的类型的小帮助器.(Clang和g ++期望方法的全名,包括它的类名).
我目前的g ++解决方案定义了一个带返回类型的静态方法std::remove_reference(decltype(*this)).(Clang和MSVC this在静态上下文中不允许).
我绝对更喜欢标准的一致性解决方案,但对于clang的特殊解决方案目前也可以.
如果没有任何作用,我必须将类的名称传递给宏,但我尽量避免这种情况,因为我已经有足够的代码使用宏.
编辑:添加一个关于反射如何工作的样本(这可能会澄清我需要的东西):
class X : public Y
{
public:
//.. constructor and such stuff...
int a;
double b;
std::string c;
CLASSHEAD(Y)
FIELD(a)
FIELD(b)
FIELD(c)
CLASSFOOT
};
Run Code Online (Sandbox Code Playgroud)
CLASSHEAD是应该定义的宏typedef.它是VAR_ARGS宏,其中参数接收基类.如上所述:可以给它类名称作为它的第一个参数(CLASSHEAD(X, Y)在示例中得到).但我几乎无法想象没有解决这种"简单"任务的方法,如对周围类型的类型...