我正在使用GNU make来编译我的C++代码,我想了解如何使我的编译可以自定义.
我在不同的地方阅读CFLAGS,CCFLAGS并CXXFLAGS用于此目的.那我该怎么用呢?如果我有额外的命令行参数编译器,我应该将它们附加CFLAGS或前置它们吗?有共同的做法吗?
为什么三个不同的变量?我想C编译器应该得到CFLAGS和CCFLAGS,而C++编译器应该得到CFLAGS和CXXFLAGS-我有没有得到它吗?
人类用户是否应该设置这些变量?做任何自动化工具(automake,autoconf,等)设置它们?我应该使用的linux系统没有定义任何这些变量 - 这是典型的吗?
目前我的Makefile看起来像这样,我觉得它有点脏:
ifdef code_coverage
GCOV_FLAG := -fprofile-arcs -ftest-coverage
else
GCOV_FLAG :=
endif
WFLAGS := -Wall
INC_FLAGS := -Istuff -Imore_stuff -Ietc
CCFLAGSINT := -O3 $(WFLAGS) $(INC_FLAGS) $(CCFLAGS)
... (somewhere in the makefile, the command-line for compilation looks like this)
$(CC) $(CCFLAGSINT) -c $< -o $@
... (somewhere in the makefile, the command-line for linking looks …Run Code Online (Sandbox Code Playgroud) 假设我在C++源文件中有以下代码(字面意思):
// #include <iostream> // superfluous, commented-out
using std::cout;
using std::endl;
int main()
{
cout << "Hello World" << endl;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
即使#include <iostream>被注释掉,我也可以编译这段代码:
g++ -include my_cpp_std_lib_hack source.cpp
Run Code Online (Sandbox Code Playgroud)
my_cpp_std_lib_hack是某个中心位置的文件,其中包含C++标准库的所有文件:
#include <ciso646>
#include <climits>
#include <clocale>
...
#include <valarray>
#include <vector>
Run Code Online (Sandbox Code Playgroud)
当然,我可以为我关心的所有编译器(即MS Visual Studio和其他一些编译器)使用适当的编译选项,并且我还使用预编译的头文件.
使用这样的hack给了我以下优点:
#include当我想要的是添加一些调试输出时,无需添加sstd::max声明的所有时间所以我想知道:我在这里做错了吗?
在编写大型项目时,这个黑客会破坏吗?
也许其他人都已经使用过这个,没有人告诉过我?
我正在尝试使用此代码读取0到255(unsigned char)之间的值.
#include<stdio.h>
int main(void)
{
unsigned char value;
/* To read the numbers between 0 to 255 */
printf("Please enter a number between 0 and 255 \n");
scanf("%u",&value);
printf("The value is %u \n",value);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
我按预期得到了以下编译器警告.
warning: format ‘%u’ expects type ‘unsigned int *’, but argument 2 has type ‘unsigned char *’
这是我对该计划的输出.
Please enter a number between 0 and 255 45 The value is 45 Segmentation fault
运行此代码时,我确实遇到了分段错误.
unsigned char使用读取值的最佳方法是什么scanf?
定义赋值运算符时,它总是如下所示:
class X {...};
X& X::operator=(...whatever...);
Run Code Online (Sandbox Code Playgroud)
也就是说,它具有返回类型"对X的引用".这里,参数(...whatever...)可以是X&,const X&只X在使用复制和交换习语时,或任何其他类型.
似乎很奇怪,无论参数如何,每个人都建议返回非const引用X.这显然允许表达式(a = b).clear(),这应该是好的.
我有不同的意见,我希望禁止般的表情(x=y).clear,(x=y)=z甚至x=y=z在我的代码.我的想法是,这些表达式在一行代码上做的事情太复杂了.所以我决定让我的赋值运算符返回void:
void X::operator=(X) {...}
void X::operator=(int) {...}
Run Code Online (Sandbox Code Playgroud)
这有哪些负面影响?(除了看起来与平常不同)
我的班级X可以用于标准容器(例如std::vector<X>)吗?
我正在使用C++ 03(如果重要的话).
当我想在不同的整数类型之间进行转换时,似乎最好的语法是使用boost::numeric_cast<>():
int y = 99999;
short x = boost::numeric_cast<short>(y); // will throw an exception if y is too large
Run Code Online (Sandbox Code Playgroud)
我从来没用过那个; 但是语法非常简单,所以一切都很顺利.
现在假设我想做一些更高级的事情:我希望它能够返回目标类型的最小值或最大值(饱和度),而不是抛出异常.我无法想出一种表达方式,但文档表明它是可能的(可能使用RawConverter策略).所有我能想到的是以下丑陋:
short x = numeric_cast<short>(max(min(y, SHORT_MAX), SHORT_MIN);
Run Code Online (Sandbox Code Playgroud)
那么我怎么能用boost来表达"饱和的演员" numeric_cast呢?
我有C++ 03代码,如下所示:
#include <boost/tr1/unordered_map.hpp>
...
std::tr1::unordered_map<std::string, int> mystuff;
...
Run Code Online (Sandbox Code Playgroud)
我开始想知道如果/当我将我的代码转换为C++ 11时,我将会受到影响,而C++ 11(我猜)没有,std::tr1::unordered_map但却有std::unordered_map.所以我提出了以下黑客攻击:
namespace std
{
using namespace ::std::tr1;
}
...
std::unordered_map<std::string, int> mystuff; // no tr1 now!
...
Run Code Online (Sandbox Code Playgroud)
它是否合法(可能std是禁止进口的东西)?是否可以更容易地使用C++ 11代码进行端口/互操作?
我有以下不编译的代码示例:
#include <stdio.h>
namespace my
{
class base1
{ // line 6
};
class base2: private base1
{
};
class derived: private base2
{
public:
// The following function just wants to print a pointer, nothing else!
void print(base1* pointer) {printf("%p\n", pointer);}
};
}
Run Code Online (Sandbox Code Playgroud)
gcc打印的错误是:
test.cpp:6:错误:`class my :: base1'无法访问
test.cpp:17:错误:在此上下文中
现在,我可以猜出问题是什么:在查看声明时print,编译器会看到base1并认为:base1是基类子对象derived* this,但是您无法访问它!虽然我打算这base1应该只是一个类型名称.
我怎么能在C++标准中看到这是一个正确的行为,而不是编译器中的错误(我确定它不是一个错误;我检查过的所有编译器都表现得如此)?
我该如何解决这个错误?所有以下修复工作,但我应该选择哪一个?
void print(class base1*pointer){}
void print(:: my :: base1*pointer){}
class base1; void print(base1*pointer){}
编辑:
int …Run Code Online (Sandbox Code Playgroud) 我正在将无范围的枚举转换为范围枚举,并且遇到了一个难题。
斯特劳斯,C ++编程语言,第4版,第8.4.1节中,作用域枚举类不隐式转换为整数类型,并为运营商提供的代码文件|,并&为如何用一个例子static_cast来工作的解决这一问题。
使用|运算符对先前定义的enum值进行的以下初始化不合法吗?
enum class FileCopy {
PreviousHDUs = 1,
CurrentHDU = 2,
FollowingHDUs = 4,
AllHDUs = PreviousHDUs | CurrentHDU | FollowingHDUs,
CurrentHeader = 8
};
int main()
{
std::cout << static_cast<int>( FileCopy::AllHDUs) << "\n";
}
Run Code Online (Sandbox Code Playgroud)
我已经在Wandbox上使用clang和gcc HEAD进行了测试--pedantic-errors,它会编译并返回预期的输出7。这并不是说合法,只是编译器似乎接受了它。
是否有明确记录的行为?我一直无法以描述此行为的方式来解析文档。
我有一些性能很重的代码执行位操作.它可以简化为以下明确定义的问题:
给定一个13位位图,构造一个26位位图,其中包含在偶数位置间隔的原始位.
为了显示:
0000000000000000000abcdefghijklm (input, 32 bits)
0000000a0b0c0d0e0f0g0h0i0j0k0l0m (output, 32 bits)
Run Code Online (Sandbox Code Playgroud)
我目前在C中以下列方式实现它:
if (input & (1 << 12))
output |= 1 << 24;
if (input & (1 << 11))
output |= 1 << 22;
if (input & (1 << 10))
output |= 1 << 20;
...
Run Code Online (Sandbox Code Playgroud)
我的编译器(MS Visual Studio)将其转换为以下内容:
test eax,1000h
jne 0064F5EC
or edx,1000000h
... (repeated 13 times with minor differences in constants)
Run Code Online (Sandbox Code Playgroud)
我想知道我是否可以更快地完成任务.我想用C语言编写代码,但是可以切换到汇编语言.
我正在重构包含许多源文件的C++项目.当前的重构步骤包括将两个文件(例如,x.cpp和y.cpp)连接成一个较大的文件(比方说xy.cpp),其中一些代码被抛出,并且还添加了一些代码.
我想告诉我的版本控制系统(Perforce,在我的情况下)生成的文件基于两个以前的文件,因此将来,当我查看修订历史时xy.cpp,我也会看到所做的所有更改x.cpp和y.cpp.
Perforce支持重命名文件,因此如果y.cpp不存在,我会确切知道该怎么做.Perforce还支持合并,所以如果我有2个不同的版本,xy.cpp它可以从中创建一个版本.由此,我发现加入两个不同的文件是可能的(不确定); 但是,我搜索了一些关于Perforce和其他源代码控制系统的文档,并没有找到任何有用的东西.
我正在尝试做什么?
它是否有一个传统的名称(搜索"合并"或"加入"的文档是不成功的)?
c++ ×6
c ×2
assembly ×1
boost ×1
coding-style ×1
enums ×1
gcc ×1
include ×1
makefile ×1
name-lookup ×1
optimization ×1
perforce ×1
refactoring ×1
scanf ×1
tr1 ×1