g ++ -Wall选项包括-Wreorder.该选项的作用如下所述.我不清楚为什么有人会关心(特别是在-Wall中默认打开它).
-Wreorder (C++ only)
Warn when the order of member initializers given in the code does not
match the order in which they must be executed. For instance:
struct A {
int i;
int j;
A(): j (0), i (1) { }
};
The compiler will rearrange the member initializers for i and j to
match the declaration order of the members, emit-ting a warning to that
effect. This warning is enabled by -Wall.
我想知道以下形式的初始化:
int array[] = {
v - 1,
array[0] + 1
} ;
Run Code Online (Sandbox Code Playgroud)
在第二个元素的初始化中,使用第一个元素的值,但尚未初始化整个数组.这恰好用g ++编译,但我不确定这是否实际上是可移植的和定义良好的构造?
我查看了通常的地方(/ usr/lib /,/ Developer/usr/lib /,/ usr/local/lib),它不在那里.
如果没有安装,有谁知道我可以在哪里找到安装说明?
谢谢!
我不确定我是否应该关闭它,但我找到了我想要的答案:
在OS X中,安装了XCode 4,libclang.dylib位于/Developer/usr/clang-ide/lib/libclang.dylib
我在退出和_exit上设置了断点,我的程序(在linux 2.6.16.46-0.12 sles10上运行的多线程应用程序)仍然以某种我无法找到的方式退出
(gdb) c ... [New Thread 47513671297344 (LWP 15279)] [New Thread 47513667103040 (LWP 15280)] [New Thread 47513662908736 (LWP 15281)] Program exited with code 0177. (gdb)
退出函数驻留在libc中,因此没有延迟加载共享库问题.有人知道一些其他神秘的退出触发器无法捕获吗?
编辑:问题现在只是学术问题.我尝试了二进制搜索调试,退出了我的一部分更改(问题消失了).在我按顺序再次应用它们之后,即使事情恢复到原始状态,我也无法再重现问题.
编辑2:我最近发现了这种错误的一个原因,这可能是这个问题的原始来源.由于历史原因,我们的产品使用邪恶的链接器标志-Bsymbolic.其中的副作用是,当一个符号未定义但被调用时,GLIBC运行时链接器将以这种方式进行轰炸,并且您在调试器中看到它作为一个退出0177的进程.当运行时链接器以这种方式中止时,我我猜它会使系统调用直接_exit(而不是使用C运行时库exit()或_exit()).这与我无法通过调试器中的退出断点来捕获这一事实是一致的.
Julia似乎有很多类似Matlab的功能.我想使用谓词从数组中进行选择.在Matlab中,我可以这样做:
>> a = 2:7 ;
>> a > 4
ans =
0 0 0 1 1 1
>> a(a>4)
ans =
5 6 7
Run Code Online (Sandbox Code Playgroud)
在朱莉娅,我找到了一种笨重的表面方式来做部分工作:
julia> a = 2:7
2:7
julia> [int(x > 3) for x in a]
6-element Array{Any,1}:
0
0
1
1
1
1
Run Code Online (Sandbox Code Playgroud)
(使用维基百科称之为列表理解).我还没有弄清楚如何在Julia中应用这样的集合来选择,但可能会在错误的树上咆哮.如何从Julia中的数组中进行谓词选择?
假设有一个基于锁的代码,如下所示,其中互斥体用于防止不适当的并发读写
mutex.get() ; // get a lock.
T localVar = pSharedMem->v ; // read something
pSharedMem->w = blah ; // write something.
pSharedMem->z++ ; // read and write something.
mutex.release() ; // release the lock.
Run Code Online (Sandbox Code Playgroud)
如果假设生成的代码是按程序顺序创建的,则仍然需要适当的硬件内存屏障,如isync,lwsync,.acq,.rel.我假设这个问题是互斥实现负责这个部分,提供一个保证pSharedMem读取和写入都发生在"get"之后,"之前"发布()[但周围的读写可以进入关键部分,因为我期望是互斥实现的标准].我还假设在适当的情况下在互斥体实现中使用volatile访问,但是volatile不用于受互斥体保护的数据(理解为什么volatile似乎不是受互斥保护的数据的必要数据实际上是这个问题).
我想了解是什么阻止编译器移动关键区域之外的pSharedMem访问.在C和C++标准中,我看到有一个序列点的概念.我发现标准文档中的大部分序列点文本都是不可理解的,但是如果我要猜测它是什么,那么声明代码不应该在有未知副作用的调用的点上重新排序.这是它的主旨吗?如果是这种情况,编译器在这里有什么样的优化自由度?
随着编译器进行棘手的优化,例如配置文件驱动的过程间内联(甚至跨文件边界),甚至未知副作用的概念也会变得模糊.
在这里以自包含的方式解释这个问题可能超出了一个简单问题的范围,因此我很容易被指向引用(最好是在线并且针对凡人程序员而不是编译器编写者和语言设计者).
编辑:(回应Jalf的回复)
我提到了像lwsync和isync这样的内存屏障指令,因为你还提到了CPU重新排序问题.我碰巧在与编译器工作者相同的实验室工作(至少对于我们的平台之一),并且已经与内在函数的实现者交谈过,我碰巧知道至少对于xlC编译器__isync()和__lwsync()(其余的原子内在函数)也是代码重新排序的障碍.在我们的自旋锁实现中,编译器可以看到这一点,因为我们的关键部分的这一部分是内联的.
但是,假设您没有使用自定义构建锁实现(就像我们碰巧那样,这可能不常见),并且只调用了一个通用接口,例如pthread_mutex_lock().在那里,编译器不会通知原型.我从未见过它表明代码不起作用
pthread_mutex_lock( &m ) ; pSharedMem->someNonVolatileVar++ ; pthread_mutex_unlock( &m ) ; pthread_mutex_lock( &m ) ; pSharedMem->someNonVolatileVar++ ; pthread_mutex_unlock( &m ) ;
除非将变量更改为volatile,否则将无法正常工作.该增量将在每个背靠背代码块中具有加载/增量/存储序列,并且如果第一增量的值在第二个寄存器中保留,则将不能正确地操作.
似乎pthread_mutex_lock()的未知副作用可以保护这种背靠背增量示例不正常行为.
我在谈论自己的结论,在线程环境中这样的代码序列的语义并没有真正严格地涵盖在C或C++语言规范中.
作为扩展,整数标量类型
__int128支持具有足够容纳128位的整数模式的目标.只需写入__int128带符号的128位整数,或写入unsigned __int128无符号的128位整数.GCC中不支持表示
__int128长整数小于128位宽的目标的类型的整数常量.
我想知道什么gcc版本增加了对这种类型的支持,或者如果有,可以直接用来测试其存在的宏.
我已经使用omniCppComplete + ctags一段时间了,并希望进一步改进代码完成.
根据这里的建议[ 1 ],gccsense和clang_complete似乎是替代品.但是,我不确定哪一个更好.他们的表现有什么想法吗?
谢谢!
更新:在我尝试clang_complete之后,我发现完成速度非常不可接受.然后我尝试使用libclang.dylib,它加速了很多,但仍然让人觉得滞后.我想我现在应该坚持使用ctags.
评估以下积分应该是非零的,并且mathematica正确地给出非零结果
Integrate[ Cos[ (Pi * x)/2 ]^2 * Cos[ (3*Pi*x)/2 ]^2, {x, -1, 1}]
Run Code Online (Sandbox Code Playgroud)
但是,尝试更一般的积分:
FullSimplify[
Integrate[Cos[(Pi x)/2]^2 Cos[((2 n + 1) Pi x)/2] Cos[((2 m + 1) Pi x)/2],
{x, -1, 1}],
Element[{m, n}, Integers]]
Run Code Online (Sandbox Code Playgroud)
产生零,对于m = n = 1,这肯定不正确
我期待一个条件表达式.是否有可能在评估积分之前"告诉"mathematica关于m和n的约束,以便它正确处理特殊情况?
内部函数_mm_slli_si128将在128位寄存器的左侧进行逻辑移位,但仅限于立即移位值,并且按字节而不是位移位.
我可以使用内部函数_mm_sll_epi64或_mm_sll_epi32在__m128i寄存器中向左移动一组值,但这些值不带"溢出"位.
对于N位移位想象我可以做类似的事情:
_mm_sll_epi64_mm_srr_epi64 (对于我想要携带的位:将它们移动到低位)(但可能还必须包括N相对于64的检查).
有没有更好的办法?