GVKun编程网logo

我的 Linux 开发项目的 Clang vs GCC(linux gcc -c)

22

本文将带您了解关于我的Linux开发项目的ClangvsGCC的新内容,同时我们还将为您解释linuxgcc-c的相关知识,另外,我们还将为您提供关于AngularJS,ng-clickvsng:点击

本文将带您了解关于我的 Linux 开发项目的 Clang vs GCC的新内容,同时我们还将为您解释linux gcc -c的相关知识,另外,我们还将为您提供关于AngularJS,ng-click vs ng:点击vs ngClick、Apple M2 for Linux 的 GCC 与 LLVM Clang 编译器性能对比、arm-linux-gcc 常用参数讲解 gcc编译器使用方法、AVR / Linux GCC C项目的常见常量的实用信息。

本文目录一览:

我的 Linux 开发项目的 Clang vs GCC(linux gcc -c)

我的 Linux 开发项目的 Clang vs GCC(linux gcc -c)

我在上大学,在一个我们使用 C 的项目中。我们探索了 GCC 和 Clang,而 Clang 似乎比 GCC 对用户更友好。因此,我想知道在 Linux
上使用 C 和 C++ 进行开发时,使用 clang 而不是 GCC 有什么优点或缺点?

就我而言,这将用于学生级别的课程,而不是生产。

如果我使用 Clang,我应该使用 GDB 调试并使用 GNU Make,还是使用另一个调试器和 make 实用程序?

答案1

小编典典

编辑:

gcc 的家伙确实提高了 gcc 的诊断体验(啊比赛)。他们创建了一个 wiki 页面来在这里展示它。gcc 4.8 现在也有很好的诊断功能(gcc 4.9x 添加了颜色支持)。Clang 仍处于领先地位,但差距正在缩小。


原来的:

对于学生,我会无条件地推荐 Clang。

gcc 和 Clang 在生成代码方面的表现现在还不清楚(虽然我认为 gcc 4.7 仍然领先,但我还没有看到确定的基准测试),但无论如何对于学生来说学习它并不重要。

另一方面,Clang 极其清晰的诊断对于初学者来说肯定更容易理解。

考虑这个简单的片段:

#include <string>#include <iostream>struct Student {std::string surname;std::string givenname;}std::ostream& operator<<(std::ostream& out, Student const& s) {  return out << "{" << s.surname << ", " << s.givenname << "}";}int main() {  Student me = { "Doe", "John" };  std::cout << me << "\n";}

您会立即注意到在定义类之后缺少分号Student,对吧 :) ?

好吧,gcc 也注意到了这一点,经过一段时间:

prog.cpp:9: error: expected initializer before ‘&’ tokenprog.cpp: In function ‘int main()’:prog.cpp:15: error: no match for ‘operator<<’ in ‘std::cout << me’/usr/lib/gcc/i686-pc-linux-gnu/4.3.4/include/g++-v4/ostream:112: note: candidates are: std::basic_ostream<_CharT, _Traits>& std::basic_ostream<_CharT, _Traits>::operator<<(std::basic_ostream<_CharT, _Traits>& (*)(std::basic_ostream<_CharT, _Traits>&)) [with _CharT = char, _Traits = std::char_traits<char>]/usr/lib/gcc/i686-pc-linux-gnu/4.3.4/include/g++-v4/ostream:121: note:                 std::basic_ostream<_CharT, _Traits>& std::basic_ostream<_CharT, _Traits>::operator<<(std::basic_ios<_CharT, _Traits>& (*)(std::basic_ios<_CharT, _Traits>&)) [with _CharT = char, _Traits = std::char_traits<char>]/usr/lib/gcc/i686-pc-linux-gnu/4.3.4/include/g++-v4/ostream:131: note:                 std::basic_ostream<_CharT, _Traits>& std::basic_ostream<_CharT, _Traits>::operator<<(std::ios_base& (*)(std::ios_base&)) [with _CharT = char, _Traits = std::char_traits<char>]/usr/lib/gcc/i686-pc-linux-gnu/4.3.4/include/g++-v4/ostream:169: note:                 std::basic_ostream<_CharT, _Traits>& std::basic_ostream<_CharT, _Traits>::operator<<(long int) [with _CharT = char, _Traits = std::char_traits<char>]/usr/lib/gcc/i686-pc-linux-gnu/4.3.4/include/g++-v4/ostream:173: note:                 std::basic_ostream<_CharT, _Traits>& std::basic_ostream<_CharT, _Traits>::operator<<(long unsigned int) [with _CharT = char, _Traits = std::char_traits<char>]/usr/lib/gcc/i686-pc-linux-gnu/4.3.4/include/g++-v4/ostream:177: note:                 std::basic_ostream<_CharT, _Traits>& std::basic_ostream<_CharT, _Traits>::operator<<(bool) [with _CharT = char, _Traits = std::char_traits<char>]/usr/lib/gcc/i686-pc-linux-gnu/4.3.4/include/g++-v4/bits/ostream.tcc:97: note:                 std::basic_ostream<_CharT, _Traits>& std::basic_ostream<_CharT, _Traits>::operator<<(short int) [with _CharT = char, _Traits = std::char_traits<char>]/usr/lib/gcc/i686-pc-linux-gnu/4.3.4/include/g++-v4/ostream:184: note:                 std::basic_ostream<_CharT, _Traits>& std::basic_ostream<_CharT, _Traits>::operator<<(short unsigned int) [with _CharT = char, _Traits = std::char_traits<char>]/usr/lib/gcc/i686-pc-linux-gnu/4.3.4/include/g++-v4/bits/ostream.tcc:111: note:                 std::basic_ostream<_CharT, _Traits>& std::basic_ostream<_CharT, _Traits>::operator<<(int) [with _CharT = char, _Traits = std::char_traits<char>]/usr/lib/gcc/i686-pc-linux-gnu/4.3.4/include/g++-v4/ostream:195: note:                 std::basic_ostream<_CharT, _Traits>& std::basic_ostream<_CharT, _Traits>::operator<<(unsigned int) [with _CharT = char, _Traits = std::char_traits<char>]/usr/lib/gcc/i686-pc-linux-gnu/4.3.4/include/g++-v4/ostream:204: note:                 std::basic_ostream<_CharT, _Traits>& std::basic_ostream<_CharT, _Traits>::operator<<(long long int) [with _CharT = char, _Traits = std::char_traits<char>]/usr/lib/gcc/i686-pc-linux-gnu/4.3.4/include/g++-v4/ostream:208: note:                 std::basic_ostream<_CharT, _Traits>& std::basic_ostream<_CharT, _Traits>::operator<<(long long unsigned int) [with _CharT = char, _Traits = std::char_traits<char>]/usr/lib/gcc/i686-pc-linux-gnu/4.3.4/include/g++-v4/ostream:213: note:                 std::basic_ostream<_CharT, _Traits>& std::basic_ostream<_CharT, _Traits>::operator<<(double) [with _CharT = char, _Traits = std::char_traits<char>]/usr/lib/gcc/i686-pc-linux-gnu/4.3.4/include/g++-v4/ostream:217: note:                 std::basic_ostream<_CharT, _Traits>& std::basic_ostream<_CharT, _Traits>::operator<<(float) [with _CharT = char, _Traits = std::char_traits<char>]/usr/lib/gcc/i686-pc-linux-gnu/4.3.4/include/g++-v4/ostream:225: note:                 std::basic_ostream<_CharT, _Traits>& std::basic_ostream<_CharT, _Traits>::operator<<(long double) [with _CharT = char, _Traits = std::char_traits<char>]/usr/lib/gcc/i686-pc-linux-gnu/4.3.4/include/g++-v4/ostream:229: note:                 std::basic_ostream<_CharT, _Traits>& std::basic_ostream<_CharT, _Traits>::operator<<(const void*) [with _CharT = char, _Traits = std::char_traits<char>]/usr/lib/gcc/i686-pc-linux-gnu/4.3.4/include/g++-v4/bits/ostream.tcc:125: note:                 std::basic_ostream<_CharT, _Traits>& std::basic_ostream<_CharT, _Traits>::operator<<(std::basic_streambuf<_CharT, _Traits>*) [with _CharT = char, _Traits = std::char_traits<char>]

Clang 也不完全是这里的主演,但仍然:

/tmp/webcompile/_25327_1.cc:9:6: error: redefinition of ''ostream'' as different kind of symbolstd::ostream& operator<<(std::ostream& out, Student const& s) {     ^In file included from /tmp/webcompile/_25327_1.cc:1:In file included from /usr/include/c++/4.3/string:49:In file included from /usr/include/c++/4.3/bits/localefwd.h:47:/usr/include/c++/4.3/iosfwd:134:33: note: previous definition is here  typedef basic_ostream<char>           ostream;        ///< @isiosfwd                                        ^/tmp/webcompile/_25327_1.cc:9:13: error: expected '';'' after top level declaratorstd::ostream& operator<<(std::ostream& out, Student const& s) {            ^            ;2 errors generated.

我特意选择了一个触发不明确错误消息的示例(来自语法中的歧义),而不是典型的“哦,我的上帝 Clang 读懂了我的想法”示例。尽管如此,我们注意到 Clang 避免了错误的泛滥。没有必要吓跑学生。

AngularJS,ng-click vs ng:点击vs ngClick

AngularJS,ng-click vs ng:点击vs ngClick

我正在学习AngularJS,我对我遇到的指令的不同用法感到有些困惑.

例如,有时我会看到类似(ng冒号点击)的内容:

<tr ng:click="..." ...>

有时我看到(ng dash click):

<tr ng-click="..." ...>

在Angular文档中,指令显示为“ngClick”(没有破折号或冒号的camelcase).另外,在某些地方,我见过:data-ng-click

这些不同形式之间有什么区别?

没有区别,这一切都取决于你的编程风格.我认为,ng-click是迄今为止最受欢迎的风格.

当你创建自己的指令时,你应该总是在javascript中使用它,然后当你把它放在你的html元素中时,你应该使用由你喜欢的味道分隔的小写版本.我总是这样做:

angular.module('Test',[]).directive('testDirective',function(){

});

然后:

<div test-directive></div>

从angular docs:

Best Practice: Prefer using the dash-delimited format (e.g. ng-bind for ngBind). If you want to use an HTML validating tool,you can instead use the data-prefixed version (e.g. data-ng-bind for ngBind). The other forms shown above are accepted for legacy reasons but we advise you to avoid them.

Apple M2 for Linux 的 GCC 与 LLVM Clang 编译器性能对比

Apple M2 for Linux 的 GCC 与 LLVM Clang 编译器性能对比

科技媒体 Phoronix 对运行在 Linux 上的 Apple M2 芯片 的 GCC 和 LLVM Clang 编译器进行了性能测试和对比。

此次测试采用的设备是 Apple M2 MacBook Air ,运行基于 Arch 的 Asahi Linux 系统(这是目前唯一能够运行最新 Apple  M2 芯片的发行版),测试基于 Linux 5.19 内核,编译器版本分别是 LLVM Clang 14.0.6 和 GCC 12.1,它们都是 Arch/Asahi 最新版本的编译器。在所有测试中,CFLAGS/CXXFLAGS 保持不变,针对 -O3 优化级别。

一共进行了数十种不同的 C/C++ 基准测试,旨在观察在运行 Linux 的 Apple M2 芯片上,GCC 12 和 Clang 14 生成的二进制文件哪个性能更佳。

测试结果如下:(选取部分结果)

可以看到,尽管 LLVM Clang 被 AArch64 供应商广泛使用,且 Apple 在上游 LLVM 上投入巨资,作为其 Xcode 使用的一部分。但至少在(Asahi)Linux 上运行时,GCC 12 编译器仍有一些二进制文件比 Clang 编译出来的更快,性能更好。

当然,LLVM Clang 也不落下风,在相当多程序中的表现超越 GCC 。

下面上最终结果:GCC 和 Clang 编译器在不同领域分别有很强的先发优势,如果采用所有测试结果的几何平均值,在运行 Asahi Linux 的 Apple M2 MacBook Air 上进行测试时,GCC 12 比 Clang 14 快了近 7%

arm-linux-gcc 常用参数讲解 gcc编译器使用方法

arm-linux-gcc 常用参数讲解 gcc编译器使用方法

我们需要编译出运行在ARM平台上的代码,所 使用 的交叉编译器为  arm-linux-gcc 。下面将 arm-linux-gcc 编译工具的一些常用命令参数介绍给大家。
在此之前首先介绍下编译器的工作过程,在 使用 GCC编译程序时,编译过程分为四个阶段:
1. 预处理(Pre-Processing)
2. 编译(Compiling)
3. 汇编(Assembling)
4. 链接(Linking)
Linux程序员可以根据自己的需要让 GCC在编译的任何阶段结束,以便检查或 使用 编译器在该阶段的输出信息,或者对最后生成的二进制文件进行控制,以便通过加入不同数量和种类的调试代码来为 今后的调试做好准备。和其它常用的编译器一样,GCC也提供了灵活而强大的代码优化功能,利用它可以生成执行效率更高的代码。

以文件example.c为例说明它的用法
0. arm-linux-gcc -o example example.c
   不加-c、-S、-E参数,编译器将执行预处理、编译、汇编、连接操作直接生成可执行代码。
    -o参数用于指定输出的文件,输出文件名为example,如果不指定输出文件,则默认输出a.out

1. arm-linux-gcc -c -o example.o example.c
   -c参数将对源程序example.c进行预处理、编译、汇编操作,生成example.0文件
   去掉指定输出选项"-o example.o"自动输出为example.o,所以说在这里-o加不加都可以

2.arm-linux-gcc -S -o example.s example.c
   -S参数将对源程序example.c进行预处理、编译,生成example.s文件
   -o选项同上

3.arm-linux-gcc -E -o example.i example.c
   -E参数将对源程序example.c进行预处理,生成example.i文件(不同版本不一样,有的将预处理后的内容打印到屏幕上)
   就是将#include,#define等进行文件插入及宏扩展等操作。
   
4.arm-linux-gcc -v -o example example.c
加上-v参数,显示编译时的详细信息,编译器的版本,编译过程等。

5.arm-linux-gcc -g -o example example.c
-g选项,加入GDB能够使用的调试信息,使用GDB调试时比较方便。

6.arm-linux-gcc -Wall -o example example.c
-Wall选项打开了所有需要注意的警告信息,像在声明之前就使用的函数,声明后却没有使用的变量等。

7.arm-linux-gcc -Ox -o example example.c
-Ox使用优化选项,X的值为空、0、1、2、3
0为不优化,优化的目的是减少代码空间和提高执行效率等,但相应的编译过程时间将较长并占用较大的内存空间。

8.arm-linux-gcc   -I /home/include -o example example.c
-Idirname: 将dirname所指出的目录加入到程序头文件目录列表中。如果在预设系统及当前目录中没有找到需要的文件,就到指定的dirname目录中去寻找。

9.arm-linux-gcc   -L /home/lib -o example example.c

-Ldirname:将dirname所指出的目录加入到库文件的目录列表中。在默认状态下,连接程序ld在系统的预设路径中(如/usr/lib)寻找所需要的库文件,这个选项告诉连接程序,首先到-L指定的目录中去寻找,然后再到系统预设路径中寻找。

10.arm-linux-gcc –static -o libexample.a example.c

静态链接库文件

 

gcc在命令行上经常使用的几个选项是: 
-c   只预处理、编译和汇编源程序,不进行连接。编译器对每一个源程序产生一个目标文件。 

-o file  确定输出文件为file。如果没有用-o选项,缺省的可执行文件的输出是a.out,目标文件和汇编文件的输出对source.suffix分别是source.o和source.s,预处理的C源程序的输出是标准输出stdout。 

-Dmacro或-Dmacro=defn   其作用类似于源程序里的#define。例如:% gcc -c -DHAVE_GDBM -DHELP_FILE=\"help\" cdict.c其中第一个- D选项定义宏HAVE_GDBM,在程序里可以用#ifdef去检查它是否被设置。第二个-D选项将宏HELP_FILE定义为字符串“help”(由于反斜线的作用,引号实际上已成为该宏定义的一部分),这对于控制程序打开哪个文件是很有用的。 

-Umacro   某些宏是被编译程序自动定义的。这些宏通常可以指定在其中进行编译的计算机系统类型的符号,用户可以在编译某程序时加上 -v选项以查看gcc缺省定义了哪些宏。如果用户想取消其中某个宏定义,用-Umacro选项,这相当于把#undef macro放在要编译的源文件的开头。 

-Idir   将dir目录加到搜寻头文件的目录列表中去,并优先于在gcc缺省的搜索目录。在有多个-I选项的情况下,按命令行上-I选项的前后顺序搜索。dir可使用相对路径,如-I../inc等。 

-O   对程序编译进行优化,编译程序试图减少被编译程序的长度和执行时间,但其编译速度比不做优化慢,而且要求较多的内存。 

-O2   允许比-O更好的优化,编译速度较慢,但结果程序的执行速度较快。 

-g   产生一张用于调试和排错的扩展符号表。-g选项使程序可以用GNU的调试程序GDB进行调试。优化和调试通常不兼容,同时使用-g和-O(-O2)选项经常会使程序产生奇怪的运行结果。所以不要同时使用-g和-O(-O2)选项。 

-fpic或-fPIC   产生位置无关的目标代码,可用于构造共享函数库。 

以上是gcc的编译选项。gcc的命令行上还可以使用连接选项。事实上,gcc将所有不能识别的选项传递给连接程序ld。连接程序ld将几个目标文件和库程序组合成一个可执行文件,它要解决对外部变量、外部过程、库程序等的引用。但我们永远不必要显式地调用ld。利用gcc命令去连接各个文件是很简单的,即使在命令行里没有列出库程序,gcc也能保证某些库程序以正确的次序出现。 

gcc的常用连接选项有下列几个: 
-Ldir   将dir目录加到搜寻-l选项指定的函数库文件的目录列表中去,并优先于gcc缺省的搜索目录。在有多个-L选项的情况下,按命令行上-L选项的前后顺序搜索。dir可使用相对路径。如-L../lib等。 

-lname   在连接时使用函数库libname.a,连接程序在-Ldir选项指定的目录下和/lib,/usr/lib目录下寻找该库文件。在没有使用-static选项时,如果发现共享函数库libname.so,则使用libname.so进行动态连接。 

-static   禁止与共享函数库连接。 

-shared   尽量与共享函数库连接

AVR / Linux GCC C项目的常见常量

AVR / Linux GCC C项目的常见常量

我正在为 Linux AVR Arduino项目创建软件.显然,整个工作分为Eclipse中的几个项目(我没有使用Arduino IDE).我想为所有这些项目使用常见的,主要是字符串的常量.我还需要备用微控制器的RAM,因此需要编译时常量.我该如何最好地实现它?我的想法是为这些常量创建一个单独的,仅限标题的项目.

使用:

class A {
public:
    static const char * const STRING;
    static const unsigned char BOOL;
};

不够好,因为我希望能够连接像这样的字符串常量:

class A {
public:
    static const char * const STRING_PART1;
    static const char * const STRING_PART2;
    static const unsigned char BOOL;
};
const char * const A::STRING_PART1 = "PART1_";
//const char * const A::STRING_PART2 = A::STRING_PART1 + "PART2"; //obvIoUsly won't compile
//const char * const A::STRING_PART2 = strcat("PART2",A::STRING_PART1); //this is not compile-time

我也不想使用define.我想用:

class A {
public:
    static const std::string STRING_PART1;
    static const std::string STRING_PART2;
}

它允许字符串连接并且是(AFAIK)编译时,但是std :: string在avr项目中不可用 – 或者我在这里错了,只是不知道如何使用它.

任何帮助赞赏.

解决方法

您可以继续使用const char * const的当前想法(如果std :: string不可用).我建议只使用#define进行分配.例:

class A {
public:
    static const char * const STRING_PART1;
    static const char * const STRING_PART2;
    static const unsigned char BOOL;
};
#define PART1_ "PART1_"  // <--- for value assignent
#define PART2_ "PART2_"
const char * const A::STRING_PART1 = PART1_;
const char * const A::STRING_PART2 = PART1_ PART2_;  // <--- ok! concatenation by compiler

关于我的 Linux 开发项目的 Clang vs GCClinux gcc -c的问题我们已经讲解完毕,感谢您的阅读,如果还想了解更多关于AngularJS,ng-click vs ng:点击vs ngClick、Apple M2 for Linux 的 GCC 与 LLVM Clang 编译器性能对比、arm-linux-gcc 常用参数讲解 gcc编译器使用方法、AVR / Linux GCC C项目的常见常量等相关内容,可以在本站寻找。

本文标签: