小编Aar*_*aid的帖子

可以添加'constexpr'来改变行为吗?

鉴于源代码中唯一不同的两个程序是否存在constexpr,程序的含义是否可能发生变化?

换句话说,如果有一个编译器选项要求编译器尝试很难推断constexpr可能的地方,它会破坏现有的标准代码和/或以不好的方式改变其含义吗?

想象一下处理一个代码库,原始开发人员忘记将其包含constexpr在可能的地方,也许是在C++ 11之前编写的代码.如果编译器推断constexpr可以帮助您继续工作,那将会很棒.当然,或许它也应该在每次进行推理时发出警告,鼓励你明确添加constexpr后者.但它仍然有用.我担心它会破坏东西吗?

到目前为止,我唯一能想到的是constexpr函数是隐含的,inline并且可能存在添加inline可能以不良方式改变事物的情况; 例如,如果您违反了单定义规则.

c++ constexpr c++11

27
推荐指数
1
解决办法
744
查看次数

memcpy/memmove给工会成员,这是否设置了"活跃"成员?

重要的澄清:一些评论者似乎认为我是从工会复制的.仔细查看memcpy,它从一个普通旧的地址复制uint32_t,它不包含在一个联合中.此外,我正在(通过memcpy)复制到一个联盟的特定成员(u.a16或者&u.x_in_a_union,不是直接复制到整个联盟本身(&u)

C++对工会非常严格 - 只有在成员写入的最后一个成员时才应该从成员中读取:

9.5 Unions [class.union] [[c ++ 11]]在一个联合中,最多一个非静态数据成员可以随时处于活动状态,即最多一个非静态的值数据成员可以随时存储在联合中.

(当然,编译器不会跟踪哪个成员是活动的.由开发人员来确保他们自己跟踪它)


更新:以下代码块是主要问题,直接反映问题标题中的文本.如果这段代码没问题,我会对其他类型进行跟进,但我现在意识到第一块代码本身很有趣.

#include <cstdint>
uint32_t x = 0x12345678;
union {
    double whatever;
    uint32_t x_in_a_union; // same type as x
} u;
u.whatever = 3.14;
u.x_in_a_union = x; // surely this is OK, despite involving the inactive member?
std::cout << u.x_in_a_union;
u.whatever = 3.14; // make the double 'active' again
memcpy(&u.x_in_a_union, &x); // same types, so should be …
Run Code Online (Sandbox Code Playgroud)

c++ object-lifetime unions language-lawyer c++11

26
推荐指数
1
解决办法
1373
查看次数

C++ 03.在编译时测试rvalue-vs-lvalue,而不仅仅是在运行时

在C++ 03中,Boost的Foreach使用这种有趣的技术,可以在运行时检测表达式是左值还是左值.(我发现通过这个StackOverflow问题:C++ 03中的Rvalues)

这是一个在运行时工作演示

(这是一个更基本的问题,当我在思考我最近的另一个问题时出现.对此的答案可能有助于我们回答另一个问题.)

现在我已经详细说明了这个问题,在编译时在C++ 03中测试rvalue-ness,我会谈谈到目前为止我一直在尝试的事情.

我希望能够在编译时进行此检查.在C++ 11中很容易,但我对C++ 03很好奇.

我正在努力建立他们的想法,但也会对不同的方法持开放态度.他们的技术的基本思想是将此代码放入一个宏:

true ? rvalue_probe() : EXPRESSION;
Run Code Online (Sandbox Code Playgroud)

它的左侧是'true' ?,因此我们可以确定永远不会评估EXPRESSION.但有趣的是,?:运算符的行为会有所不同,具体取决于它的参数是左值还是右值(单击上面的链接获取详细信息).特别是,它将rvalue_probe以两种方式之一转换我们的对象,具体取决于EXPRESSION是否为左值:

struct rvalue_probe
{
    template< class R > operator       R () { throw "rvalue"; }
    template< class L > operator       L & () const { throw "lvalue"; }
    template< class L > operator const L & () const { throw "const lvalue"; }
};
Run Code Online (Sandbox Code Playgroud)

这在运行时有效,因为可以捕获抛出的文本并用于分析EXPRESSION是左值还是右值.但我希望在编译时能够识别正在使用的转换. …

c++ rvalue language-lawyer c++03

22
推荐指数
1
解决办法
1797
查看次数

g ++不允许在lambda中通过引用对const对象进行广义捕获?

这被g ++(4.9.3和5.2.0)拒绝,但是被clang 3.5.0接受:

int main() { 
    const int ci = 0;
    auto lambda = [ &cap = ci ]() { };
}
Run Code Online (Sandbox Code Playgroud)

g ++给出error: binding ‘const int’ to reference of type ‘int&’ discards qualifiers.似乎g ++拒绝允许捕获非const引用,当然除了使用普通的旧C++ 11捕获[&ci].这似乎是一个非常奇怪的约束,也许是g ++中的一个错误?

c++ lambda c++14

21
推荐指数
1
解决办法
862
查看次数

字面数字是否可变?

当然,这不会编译:

int &z = 3; // error: invalid initialization of non-const reference ....
Run Code Online (Sandbox Code Playgroud)

这将编译:

const int &z = 3; // OK
Run Code Online (Sandbox Code Playgroud)

现在,考虑一下:

const int y = 3;
int && yrr = y; // const error (as you would expect)
int && yrr = move(y); // const error (as you would expect)
Run Code Online (Sandbox Code Playgroud)

这些下一行确实为我编译.我认为不应该.

int && w = 3;
int && yrr = move(3);
void bar(int && x) {x = 10;}
bar(3);
Run Code Online (Sandbox Code Playgroud)

最后两行不会允许文字3被修改吗?3与const int有什么区别?最后,"修改"文字是否有任何危险?

(g ++ - 4.6(GCC)4.6.2 with …

c++ const rvalue-reference c++11

17
推荐指数
1
解决办法
258
查看次数

为什么当我看起来最新并且推拉(没有文件)修复它时,git说我提前40次提交?

我切换到master,它说我提前40次提交:

$ git checkout master
Switched to branch 'master'
Your branch is ahead of 'origin/master' by 40 commits.
Run Code Online (Sandbox Code Playgroud)

但是,当我接受拉动时,它说我是最新的:

$ git pull origin master
From https://github.com/dmcouncil/dmWorkflow
 * branch            master     -> FETCH_HEAD
Already up-to-date.
Run Code Online (Sandbox Code Playgroud)

但是我可以解决这个问题(删除40 commitsmsg):

Michaels-MacBook-Pro-2:dmWorkflow durrantm$ git push origin master
Everything up-to-date
Run Code Online (Sandbox Code Playgroud)

现在' 40 commits'信息消失了:

$ git status
# On branch mdd_play_settings_and_topics_reports
nothing to commit (working directory clean)
Run Code Online (Sandbox Code Playgroud)

为什么我必须做额外的推动(似乎没什么)才能同步?
我能采取更好的方法吗?

git branch github master

11
推荐指数
1
解决办法
2655
查看次数

最简单的经验法则是避免违反严格别名规则?

在阅读另一个关于别名的问题(什么是严格的别名规则?)及其最佳答案时,我意识到我仍然不完全满意,即使我认为我在那里理解了它.

(这个问题现在被标记为C和C++.如果您的答案仅涉及其中一个,请澄清哪个.)

所以我想了解如何在这个领域做一些开发,以积极的方式进行指针,但是使用一个简单的保守规则来确保我不引入UB.我在这里提出了这样的规则.

(更新:当然,我们可以避免所有类型的惩罚.但这不是很有教育意义.除非当然,除了例外之外,确实存在明确定义的union异常.)

更新2:我现在明白为什么这个问题中提出的方法不正确.但是,知道是否存在简单,安全的替代方案仍然很有趣.截至目前,至少有一个答案提出了这样的解决方案.

这是最初的例子:

int main()
{
   // Get a 32-bit buffer from the system
   uint32_t* buff = malloc(sizeof(Msg));

   // Alias that buffer through message
   Msg* msg = (Msg*)(buff);

   // Send a bunch of messages    
   for (int i =0; i < 10; ++i)
   {
      msg->a = i;
      msg->b = i+1;
      SendWord(buff[0] );
      SendWord(buff[1] );   
   }
}
Run Code Online (Sandbox Code Playgroud)

重要的是:

Msg* msg = (Msg*)(buff);
Run Code Online (Sandbox Code Playgroud)

这意味着现在有两个指针(不同类型)指向相同的数据.我的理解是,任何通过其中一个写入的尝试都会使另一个指针基本上无效.('无效'是指我们可以安全地忽略它,但通过无效指针读取/写入是UB.)

Msg* msg = (Msg*)(buff);
msg->a = …
Run Code Online (Sandbox Code Playgroud)

c c++ strict-aliasing

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

投射指针和三元?:运算符.我重新改造了车轮吗?

这段代码的最后一行无法编译 castingAndTernary.cpp:15: error: conditional expression between distinct pointer types ‘D1*’ and ‘D2*’ lacks a cast

一个非常聪明的编译器可以没有任何困难,因为它们都可以安全地转换为B*(基类).我不愿意使用static_cast和dynamic_cast等等 - 我担心有一天我会混淆这些类并获得未定义的行为.这就是我创建up_cast模板的原因.此模板在允许的转换中完成了最低限度.有更简单的方法吗?还有其他的解决方法,但我不禁想到,我可以使用更简单,更安全的东西吗?

struct B{ };
struct D1 : public B{ };
struct D2 : public B{ };

template<typename T,typename V>
T up_cast(V x) {
        return x;
}
int main() {
        bool boolean_expression = true;
        B * b;
        b = new D1;
        b = new D2;
        b = boolean_expression ? up_cast<B*>(new D1) : up_cast<B*>(new D2);
        b = boolean_expression ? new D1 : new …
Run Code Online (Sandbox Code Playgroud)

c++ casting ternary-operator

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

"恒定"复杂性究竟意味着什么?时间?副本/动作的数量?

我可以想到C++中的三个操作可以在某种意义上描述为具有"恒定"的复杂性.我已经看到了一些关于这意味着什么的辩论(*),在我看来,我们可以说"所有这些操作都是不变的,但有些操作比其他操作更稳定":-)

(编辑2:如果你已经认为你已经知道了答案,那么请先阅读一些关于这个问题的辩论,然后再过早说:C++中的数据结构究竟是什么?很多人都有很高的分数,他们正在争论"常数"意味着什么.我的问题并不像你想象的那么明显!)

(编辑:我不需要什么复杂性"意味着我要一个明确的答案,或许与C++标准报价的底漆,它告诉我们究竟是什么被认为是恒定的.处理器蜱,真实世界的时间,或其他什么?在其他线程上,有些人认为时间与C++标准所要求的完全无关.)

标准中的这些复杂性保证是否适用于运行的运行时?或者他们只是指定所包含对象可能发生的(最大)份数/移动次数?什么'摊销'是什么意思?

1.给定(非空)vector<int> v,以下在运行时显然是常量:

swap(v.front(), v.back());
Run Code Online (Sandbox Code Playgroud)

(虽然一个学究者可能会指出它取决于数据是在缓存中还是换出来的等等!).

2.给定一个list<int> l,做一个push_back很简单.正好分配了一个新项目,并且链接列表中的一些指针被洗牌.每个push_front涉及一个分配,总是具有相同的内存量,因此这显然是相当"恒定"的.但是,当然,进行分配的时间可能非常多变.内存管理可能需要花费大量时间才能找到合适的空闲内存.

3.但是,做一个push_backvector<int>更是不可预知的.大多数情况下,它会非常快,但它会不时地为所有数据重新分配空间并将每个元素复制到新位置.因此,它在运行时方面的可预测性不如单个list::push_front,但它仍然被称为常量(摊销).平均而言,向向量添加大量数据将带来与添加量无关的复杂性,这就是为什么它被称为"摊销常数"时间.(我对吗?)

最后,我要求int避免使用其他类型的复杂性.例如,a vector< vector<int> >可能稍微复杂一点,因为向量(向量)的每个元素可能具有不同的大小,例如,交换两个元素并不像上面的情况1那样恒定.但理想情况下,我们可以回答所有人vector<T>,而不仅仅是T=int.

(*)有关辩论的一个例子,请参阅对这些答案的评论:究竟什么数据结构是C++中的deques?

c++ complexity-theory time-complexity

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

为什么`vector <int> v {{5,6}};`工作?我以为只允许一对{}被允许?

给定一个A带有两个构造函数的类,分别取initializer_list<int>initializer_list<initializer_list<int>>

A v{5,6};
Run Code Online (Sandbox Code Playgroud)

叫前者,和

A v{{5,6}};
Run Code Online (Sandbox Code Playgroud)

按预期调用后者.(clang3.3,显然gcc表现不同,请看答案.标准需要什么?)

但是如果我删除第二个构造函数,那么A v{{5,6}};仍然编译并使用第一个构造函数.我没想到这一点.我认为这A v{5,6}将是访问构造函数的唯一方法initializer_list<int>.

(我发现这一点的同时与玩弄std::vector这个问题,我问在Reddit上,但我创建了自己的A级,以确保它不只是一个对接口的怪癖std::vector.)

initializer-list c++11

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