小编Joh*_*nck的帖子

在 CRTP 基类构造函数中向下转换为派生类:UB 与否?

考虑以下类:

template <class Derived>
class BaseCRTP {
  private:
    friend class LinkedList<Derived>;
    Derived *next = nullptr;

  public:
    static LinkedList<Derived> instances;

    BaseCRTP() {
        instances.insert(static_cast<Derived *>(this));
    }
    virtual ~BaseCRTP() {
        instances.remove(static_cast<Derived *>(this));
    }
};
Run Code Online (Sandbox Code Playgroud)
struct Derived : BaseCRTP<Derived> {
    int i;
    Derived(int i) : i(i) {}
};
Run Code Online (Sandbox Code Playgroud)
int main() {
    Derived d[] = {1, 2, 3, 4};
    for (const Derived &el : Derived::instances) 
        std::cout << el.i << std::endl;
}
Run Code Online (Sandbox Code Playgroud)

我知道,这是不确定的行为来访问的成员DerivedBaseCRTP<Derived>构造函数(或析构函数),因为Derived构造函数执行BaseCRTP<Derived>构造(和析构函数的其他方式)。

我的问题是:在不访问任何成员的 …

c++ crtp downcast undefined-behavior language-lawyer

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

SO_NOSIGPIPE没有被删除

我想在tcp套接字中使用SO_NOSIGPIPE.

  int set = 1;
  setsockopt(sockDesc, SOL_SOCKET, SO_NOSIGPIPE, (void *)&set, sizeof(int);
Run Code Online (Sandbox Code Playgroud)

但是会出现错误:

   error: SO_NOSIGPIPE was not declared in this scope
Run Code Online (Sandbox Code Playgroud)

是否需要任何头文件才能使用它.我通过互联网搜索但没有得到任何有用的解决方案.

c sockets tcp

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

将char数组转换为其他类型会违反严格别名规则吗?

考虑这两个功能:

int f1()
{
  alignas(int) char buf[sizeof(int)] = {};
  return *reinterpret_cast<int*>(buf);
}

int f2()
{
  alignas(int) char buf[sizeof(int)] = {};
  char* ptr = buf;
  return *reinterpret_cast<int*>(ptr);
}
Run Code Online (Sandbox Code Playgroud)

GCC警告说,第一个违反严格别名规则.但第二个是好的.

Clang接受了两个没有投诉.

警告是否合法?

c++ strict-aliasing compiler-warnings language-lawyer reinterpret-cast

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

为什么GCC不能消除多个继承函数的歧义(但是clang可以)?

可能重复:
为什么具有相同名称但签名不同的多重继承函数不会被视为重载函数?

这无法使用g ++ 4.6.1在指定的位置进行编译:

enum Ea { Ea0 };
enum Eb { Eb0 };

struct Sa { void operator()(Ea) {} };
struct Sb { void operator()(Eb) {} };
struct Sbroken : Sa, Sb {};

struct Sworks {
    void operator()(Ea) {}
    void operator()(Eb) {}
};

int main() {
    Sworks()(Ea0);
    Sbroken()(Ea0); // g++ can't disambiguate Ea vs. Eb
}
Run Code Online (Sandbox Code Playgroud)

Clang 2.8确实编译了这段代码,这让我不确定代码是否真的有效C++.我乐观地总结出clang是对的并且g ++是错误的,但后来我做了一个小改动,使得clang有类似的错误:

enum Ea { Ea0 };
enum Eb { Eb0 };

struct Sa { void f(Ea) {} };
struct Sb …
Run Code Online (Sandbox Code Playgroud)

c++ overloading operator-overloading multiple-inheritance ambiguous

12
推荐指数
1
解决办法
799
查看次数

为什么C++ numeric_limits <enum_type> :: max()== 0?

这里有一些代码可能会起作用:

#include <cassert>
#include <limits>

enum test { A = 1 };

int main()
{
    int max = std::numeric_limits<test>::max();
    assert(max > 0);
}
Run Code Online (Sandbox Code Playgroud)

但它在Linux上的GCC(4.6.2)和clang(2.9)都失败了:枚举类型的max()实际上是零!即使您使用C++ 11枚举类型说明符来明确说明您希望枚举具有哪种类型,这仍然是正确的.

为什么是这样?至于C++ 11的行为,它是否被明确要求?我在N2347中没有提到它,这是关于强类型枚举的论文.

c++ enums numeric-limits c++11 strongly-typed-enum

12
推荐指数
1
解决办法
6060
查看次数

基础不在[2,36](GCC)时C++ 11 std :: stoi默默失败

我在Linux上使用GCC 4.9.0.这是我的测试程序:

#include <iostream>
#include <string>

using namespace std;

int main(int argc, char* argv[])
{
  size_t pos = 42;
  cout << "result: " << stoi(argv[1], &pos, atoi(argv[2])) << '\n';
  cout << "consumed: " << pos << '\n';
}
Run Code Online (Sandbox Code Playgroud)

这是预期的结果:

$ ./a.out 100 2
result: 4
consumed: 3
Run Code Online (Sandbox Code Playgroud)

也就是说,它将基数2中的"100"解析为数字4并消耗所有3个字符.

我们可以做类似基地36:

 $ ./a.out 100 36
result: 1296
consumed: 3
Run Code Online (Sandbox Code Playgroud)

但更大的基地怎么样?

$ ./a.out 100 37
result: 0
consumed: 18446744073707449552
Run Code Online (Sandbox Code Playgroud)

这是什么?本pos应该是它停止解析的索引.这里接近std::string::npos但不完全(减去几百万).如果我没有编译优化则pos18446744073703251929相反,所以它看起来像垃圾未初始化,尽管我做初始化(42).事实上,valgrind抱怨说:

Conditional jump or move depends …
Run Code Online (Sandbox Code Playgroud)

c++ gcc std c++11

12
推荐指数
1
解决办法
822
查看次数

我可以让GCC警告将过多的类型传递给函数吗?

以下是一些明显有缺陷的代码,我认为编译器应该发出诊断信息.但是,即使有我能想到的所有警告选项,它既不会gccg++不会:-pedantic -Wall -Wextra

#include <stdio.h>

short f(short x)
{
    return x;
}

int main()
{
    long x = 0x10000007;   /* bigger than short */
    printf("%d\n", f(x));  /* hoping for a warning here */
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

有没有办法制作gccg++警告这个?另外,您是否有另一个编译器在默认情况下或在相当常见的额外警告配置中对此进行警告?

注意:我正在使用GCC(C和C++编译器)版本4.2.4.

编辑:我刚刚找到gcc -Wconversion了诀窍,但是相同的选项g++没有,我真的在这里使用C++,所以我需要一个解决方案g++(现在我想知道为什么-Wconversion似乎不是这样).

编辑:http://gcc.gnu.org/bugzilla/show_bug.cgi? id = 34389建议这可能会修复g++ 4.4...也许?我还不清楚它是否是同一个问题和/或修复是否真的出现在那个版本中.也许有4.3或4.4的人可以试试我的测试用例.

c c++ gcc g++ compiler-warnings

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

Python 3使用ROUND_HALF_UP上下文舍入一半

任何人都可以解释或提出一个解决方法,为什么当我在Python 3中舍入小数,并将上下文设置为舍入一半时,它将舍入2.5到2,而在Python 2中它正确舍入为3:

Python 3.4.3和3.5.2:

>>> import decimal
>>> context = decimal.getcontext()
>>> context.rounding = decimal.ROUND_HALF_UP
>>> round(decimal.Decimal('2.5'))
2
>>> decimal.Decimal('2.5').__round__()
2
>>> decimal.Decimal('2.5').quantize(decimal.Decimal('1'), rounding=decimal.ROUND_HALF_UP)
Decimal('3')
Run Code Online (Sandbox Code Playgroud)

Python 2.7.6:

>>> import decimal
>>> context = decimal.getcontext()
>>> context.rounding = decimal.ROUND_HALF_UP
>>> round(decimal.Decimal('2.5'))
3.0
>>> decimal.Decimal('2.5').quantize(decimal.Decimal('1'), rounding=decimal.ROUND_HALF_UP)
Decimal('3')
Run Code Online (Sandbox Code Playgroud)

python decimal rounding python-3.x

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

Python doctest:有条件地跳过测试

我知道如何使用跳过文档测试# doctest: +SKIP,但我无法弄清楚如何跳过测试有时,根据运行状态.例如:

>>> if os.path.isfile("foo"):
...    open("foo").readlines()
... else:
...    pass # doctest: +SKIP
['hello', 'world']
Run Code Online (Sandbox Code Playgroud)

这就是我想要做的事情.我也接受运行测试的解决方案,但是如果不满足条件,则将预期结果更改为带有回溯的异常(即无条件地运行测试但修改预期结果).

python doctest

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

设置种子提升::随机

我想通过使用不同的种子数重置随机序列.运行此测试代码时:

boost::mt19937 gener(1);
boost::normal_distribution<> normal(0,1);
boost::variate_generator<boost::mt19937&,boost::normal_distribution<> > rng(gener, normal);
cout << rng() << endl;
cout << rng() << endl;
cout << rng() << endl;
gener.seed(2);
cout << rng() << endl;
cout << rng() << endl;
gener.seed(1);
cout << rng() << endl;
gener.seed(2);
cout << rng() << endl;
gener.seed(3);
cout << rng() << endl;
Run Code Online (Sandbox Code Playgroud)

我得到以下输出:

# seed(1) via constructor
-2.971829031
1.706951063
-0.430498971
# seed(2)
-2.282022417
-0.5887503675
# seed(1)
0.2504171986
# seed(2)
-0.5887503675
# seed(3)
0.2504171986
Run Code Online (Sandbox Code Playgroud)

显然我做错了.我怎么能克服这个问题?

c++ random boost seed

9
推荐指数
2
解决办法
1万
查看次数