我知道C++ 中的"未定义行为"几乎可以让编译器做任何想做的事情.但是,我遇到了让我感到惊讶的崩溃,因为我认为代码足够安全.
在这种情况下,真正的问题仅发生在使用特定编译器的特定平台上,并且仅在启用了优化时才发生.
我尝试了几件事来重现问题并将其简化到最大程度.这是一个名为的函数的摘录Serialize,它将获取bool参数,并将字符串true或复制false到现有的目标缓冲区.
如果bool参数是未初始化的值,那么这个函数是否会在代码审查中,没有办法告诉它实际上可能会崩溃?
// Zero-filled global buffer of 16 characters
char destBuffer[16];
void Serialize(bool boolValue) {
// Determine which string to print based on boolValue
const char* whichString = boolValue ? "true" : "false";
// Compute the length of the string we selected
const size_t len = strlen(whichString);
// Copy string into destination buffer, which is zero-filled (thus already null-terminated)
memcpy(destBuffer, whichString, len);
}
Run Code Online (Sandbox Code Playgroud)
如果使用clang 5.0.0 +优化执行此代码,它将/可能崩溃.
boolValue ? "true" …
更新2017-05-17.我不再为出现此问题的公司工作,也无法访问Delphi XEx.当我在那里时,问题通过迁移到混合FPC + GCC(Pascal + C)来解决,NEON内在函数用于某些例程,它们有所不同.(强烈建议使用FPC + GCC,因为它可以使用标准工具,特别是Valgrind.)如果有人能够通过可靠的示例演示他们如何实际能够从Delphi XEx生成优化的ARM代码,我很高兴接受答案.
Embarcadero的Delphi编译器使用LLVM后端为Android设备生成本机ARM代码.我有大量的Pascal代码需要编译到Android应用程序中,我想知道如何使Delphi生成更高效的代码.现在,我甚至都没有谈论自动SIMD优化等高级功能,只是关于生成合理的代码.当然必须有一种方法将参数传递给LLVM端,或以某种方式影响结果?通常,任何编译器都会有很多选项来影响代码编译和优化,但是Delphi的ARM目标似乎只是"优化开/关"就是这样.
LLVM应该能够产生合理紧密且合理的代码,但似乎Delphi以一种奇怪的方式使用它的设施.Delphi希望非常频繁地使用堆栈,它通常只利用处理器的寄存器r0-r3作为临时变量.也许是最疯狂的,似乎是将正常的32位整数加载为四个1字节的加载操作.如何让Delphi产生更好的ARM代码,而且没有逐字节麻烦的Android?
起初我认为逐字节加载是用于从big-endian交换字节顺序,但事实并非如此,它实际上只是加载一个带有4个单字节加载的32位数字.*可能是加载完整的32位而不进行未对齐的字大小的内存加载.(是否应该避免这是另一回事,这将暗示整个事情是编译器错误)*
让我们来看看这个简单的函数:
function ReadInteger(APInteger : PInteger) : Integer;
begin
Result := APInteger^;
end;
Run Code Online (Sandbox Code Playgroud)
即使启用了优化,带有更新包1的Delphi XE7以及XE6也会为该功能生成以下ARM汇编代码:
Disassembly of section .text._ZN16Uarmcodetestform11ReadIntegerEPi:
00000000 <_ZN16Uarmcodetestform11ReadIntegerEPi>:
0: b580 push {r7, lr}
2: 466f mov r7, sp
4: b083 sub sp, #12
6: 9002 str r0, [sp, #8]
8: 78c1 ldrb r1, [r0, #3]
a: 7882 ldrb r2, [r0, #2]
c: ea42 2101 orr.w r1, r2, r1, lsl #8
10: 7842 ldrb r2, [r0, #1] …Run Code Online (Sandbox Code Playgroud) 我有许多使用CMake构建的项目,我希望能够轻松地在使用GCC或Clang/LLVM进行编译之间进行切换.我相信(请纠正我,如果我错了!)使用Clang我需要设置以下内容:
SET (CMAKE_C_COMPILER "/usr/bin/clang")
SET (CMAKE_C_FLAGS "-Wall -std=c99")
SET (CMAKE_C_FLAGS_DEBUG "-g")
SET (CMAKE_C_FLAGS_MINSIZEREL "-Os -DNDEBUG")
SET (CMAKE_C_FLAGS_RELEASE "-O4 -DNDEBUG")
SET (CMAKE_C_FLAGS_RELWITHDEBINFO "-O2 -g")
SET (CMAKE_CXX_COMPILER "/usr/bin/clang++")
SET (CMAKE_CXX_FLAGS "-Wall")
SET (CMAKE_CXX_FLAGS_DEBUG "-g")
SET (CMAKE_CXX_FLAGS_MINSIZEREL "-Os -DNDEBUG")
SET (CMAKE_CXX_FLAGS_RELEASE "-O4 -DNDEBUG")
SET (CMAKE_CXX_FLAGS_RELWITHDEBINFO "-O2 -g")
SET (CMAKE_AR "/usr/bin/llvm-ar")
SET (CMAKE_LINKER "/usr/bin/llvm-ld")
SET (CMAKE_NM "/usr/bin/llvm-nm")
SET (CMAKE_OBJDUMP "/usr/bin/llvm-objdump")
SET (CMAKE_RANLIB "/usr/bin/llvm-ranlib")
Run Code Online (Sandbox Code Playgroud)
是否有一种在这些和默认GCC变量之间切换的简单方法,最好是作为系统范围的变更而不是项目特定的(即不只是将它们添加到项目的CMakeLists.txt中)?
另外,llvm-*在使用clang而不是gcc编译时是否有必要使用程序而不是系统默认值?有什么不同?
我希望clang将我的C/C++代码编译为LLVM字节码而不是二进制可执行文件.我怎样才能做到这一点?如果我得到LLVM字节码,我怎么能把它进一步编译成二进制可执行文件.
基本上我想LLVM在编译成二进制可执行文件之前将一些自己的代码添加到字节码中.
我在OS X上有关于llvm,clang和gcc的问题.
llvm-gcc 4.2,llvm 2.0和clang有什么区别?我知道它们都建立在llvm之上,但它们有何不同?
除了更快的编译,llvm优于gcc的优势是什么?
我正在研究使用clang的代码完成机制时潜在的代码完成速度.下面描述的流程是我在rtags中发现的Anders Bakken.
翻译单元由守护程序监视文件进行解析以进行更改.这是通过被调用的clang_parseTranslationUnit和相关的函数(reparse*,dispose*)来完成的.当用户在源文件中的给定行和列请求完成时,守护程序将缓存的转换单元传递给源文件的最后保存版本和当前源文件clang_codeCompleteAt.(Clang CodeComplete docs).
传递给clang_parseTranslationUnit(来自CompletionThread :: process,第271行)的标志是CXTranslationUnit_PrecompiledPreamble|CXTranslationUnit_CacheCompletionResults|CXTranslationUnit_SkipFunctionBodes.传递给clang_codeCompleteAt(来自CompletionThread :: process,第305行)的标志是CXCodeComplete_IncludeMacros|CXCodeComplete_IncludeCodePatterns.
调用clang_codeCompleteAt非常慢 - 即使在完成位置是合法成员访问代码的情况下,也需要大约3-5秒来获得完成,这是文档中提到的预期用例的子集clang_codeCompleteAt.IDE代码完成标准似乎太慢了.有没有办法加速这个?
可以将哪些语言编译为Web程序集(或wasm)?
我相信现在可以将C,C++和rust(实验)编译成Web程序集,使用llvm编译器后端,目前不支持Java,swift和C#等语言,但可能成为未来开发的候选者.
我不相信javascript可以编译为wasm. https://github.com/WebAssembly/design/issues/219
是否有适用于Windows的C/C++ IDE,它与LLVM编译器(和Clang C/C++分析器)集成,就像现代Xcode一样.
我有Dev-Cpp(它使用过时的GCC)和Code :: Blocks(带有一些GCC).但GCC给了我非常神秘的错误信息.我想从Clang前端获得一些用户友好的错误消息.
是的,Clang无法用于复杂的C++代码,但是主干Clang已经可以编译LLVM本身了.所以我想知道是否有任何LLVM IDE正在开发或测试版中.
是的,我可以使用Clang作为其他编译器与GCC兼容的IDE.但是有没有与Clang 集成的 IDE ?Clang具有不同的输出格式,因此IDE必须解析它.Clang可以提供IDE解析源.Clang有一个分析选项,必须在IDE中支持.看看,例如http://iosdevelopertips.com/xcode/static-code-analysis-clang-and-xcode-3-2.html
而Clang最需要的功能是智能自动完成功能,因此IDE只能建议使用语法正确的变体,例如只列出此结构的类字段,类.
结果:(从答案中合并):
目前我对ARM一般感兴趣,特别是iphone/android目标.但我只想更多地了解铿锵声,因为它感觉在未来几年中扮演重要角色.
我试过了
clang -cc1 --help|grep -i list
clang -cc1 --help|grep arch|grep -v search
clang -cc1 --help|grep target
-triple <value> Specify target triple (e.g. i686-apple-darwin9)
Run Code Online (Sandbox Code Playgroud)
我知道clang有-triplet参数,但是如何列出所有可能的值呢?我发现clang在交叉编译方面与gcc非常不同,在GCC世界中你应该为所有东西都有单独的二进制文件,比如PLATFORM_make或PLATFORM_ld(i*86-pc-cygwin i*86 - * - linux-gnu等.http: ://git.savannah.gnu.org/cgit/libtool.git/tree/doc/PLATFORMS)
在clang世界中,它只有一个二进制文件(正如我在一些论坛上看到的那样).但是如何获得支持的目标列表?如果我的目标不支持我的发行版(linux/windows/macos/whatever),我怎么能得到支持更多平台的那个?
如果我SVN最新铿锵如下:
svn co http://llvm.org/svn/llvm-project/cfe/trunk clang
Run Code Online (Sandbox Code Playgroud)
我会获得大多数平台吗?看起来Clang并没有立即考虑交叉编译,但是因为它基于llvm,它理论上应该是非常交叉友好的?谢谢!