小编ana*_*lyg的帖子

CFLAGS,CCFLAGS,CXXFLAGS - 这些变量到底控制着什么?

我正在使用GNU make来编译我的C++代码,我想了解如何使我的编译可以自定义.

我在不同的地方阅读CFLAGS,CCFLAGSCXXFLAGS用于此目的.那我该怎么用呢?如果我有额外的命令行参数编译器,我应该将它们附加CFLAGS或前置它们吗?有共同的做法吗?

为什么三个不同的变量?我想C编译器应该得到CFLAGSCCFLAGS,而C++编译器应该得到CFLAGSCXXFLAGS-我有没有得到它吗?

人类用户是否应该设置这些变量?做任何自动化工具(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)

gcc makefile naming-conventions

64
推荐指数
3
解决办法
10万
查看次数

废除C++中的包含文件

假设我在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当我想要的是添加一些调试输出时,无需添加s
  • 无需记住或查找std::max声明的所有时间
  • 感觉STL神奇地内置于语言中

所以我想知道:我在这里做错了吗?

在编写大型项目时,这个黑客会破坏吗?

也许其他人都已经使用过这个,没有人告诉过我?

c++ coding-style include

23
推荐指数
2
解决办法
1164
查看次数

使用scanf读取unsigned char

我正在尝试使用此代码读取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

c scanf

20
推荐指数
1
解决办法
3万
查看次数

返回类型的赋值运算符

定义赋值运算符时,它总是如下所示:

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(如果重要的话).

c++ assignment-operator

16
推荐指数
1
解决办法
592
查看次数

使用boost :: numeric_cast <>

当我想在不同的整数类型之间进行转换时,似乎最好的语法是使用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++ boost type-conversion

14
推荐指数
1
解决办法
6434
查看次数

将std :: tr1导入std - 是否合法?它是否提高了可移植性?

我有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代码进行端口/互操作?

c++ compatibility tr1

14
推荐指数
2
解决办法
755
查看次数

私有继承:名称查找错误

我有以下不编译的代码示例:

#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++ class-members private-inheritance name-lookup

13
推荐指数
1
解决办法
276
查看次数

为什么作用域枚举允许使用| 使用先前分配的值进行初始化时的运算符?

我正在将无范围的枚举转换为范围枚举,并且遇到了一个难题。

斯特劳斯,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。这并不是说合法,只是编译器似乎接受了它。

是否有明确记录的行为?我一直无法以描述此行为的方式来解析文档

c++ enums bitwise-operators language-lawyer

12
推荐指数
2
解决办法
199
查看次数

如何在位图中的位之间插入零?

我有一些性能很重的代码执行位操作.它可以简化为以下明确定义的问题:

给定一个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语言编写代码,但是可以切换到汇编语言.

  • 我可以使用一些MMX/SSE指令一次处理所有位吗?
  • 也许我可以使用乘法?(乘以0x11111111或其他一些神奇的常数)
  • 使用条件设置指令(SETcc)而不是条件跳转指令会更好吗?如果是,我如何让编译器为我生成这样的代码?
  • 还有其他想法如何让它更快?
  • 任何想法如何进行逆位图转换(我必须实现它,位不太重要)?

c optimization assembly bit-manipulation

11
推荐指数
2
解决办法
1648
查看次数

如何在版本控制系统中连接两个文件

我正在重构包含许多源文件的C++项目.当前的重构步骤包括将两个文件(例如,x.cppy.cpp)连接成一个较大的文件(比方说xy.cpp),其中一些代码被抛出,并且还添加了一些代码.

我想告诉我的版本控制系统(Perforce,在我的情况下)生成的文件基于两个以前的文件,因此将来,当我查看修订历史时xy.cpp,我也会看到所做的所有更改x.cppy.cpp.

Perforce支持重命名文件,因此如果y.cpp不存在,我会确切知道该怎么做.Perforce还支持合并,所以如果我有2个不同的版本,xy.cpp它可以从中创建一个版本.由此,我发现加入两个不同的文件是可能的(不确定); 但是,我搜索了一些关于Perforce和其他源代码控制系统的文档,并没有找到任何有用的东西.

我正在尝试做什么?
它是否有一个传统的名称(搜索"合并"或"加入"的文档是不成功的)?

version-control refactoring perforce

10
推荐指数
1
解决办法
369
查看次数