相关疑难解决方法(0)

什么是严格别名规则?

当询问C中常见的未定义行为时,灵魂比我提到的严格别名规则更加开明.
他们在说什么?

c strict-aliasing undefined-behavior type-punning

778
推荐指数
10
解决办法
19万
查看次数

如何制作便携式isnan/isinf功能

我一直在使用isinf,isnan在Linux平台上运行完美的功能.但是这在OS-X上不起作用,所以我决定使用std::isinf std::isnan哪种适用于Linux和OS-X.

但英特尔编译器无法识别它,我猜它是英特尔编译器中的一个错误,根据http://software.intel.com/en-us/forums/showthread.php?t=64188

所以,现在我只是想避免麻烦和定义自己的isinf,isnan执行.

有谁知道如何做到这一点?

编辑:

我最终在我的源代码中进行了制作isinf/ isnan工作

#include <iostream>
#include <cmath>

#ifdef __INTEL_COMPILER
#include <mathimf.h>
#endif

int isnan_local(double x) { 
#ifdef __INTEL_COMPILER
  return isnan(x);
#else
  return std::isnan(x);
#endif
}

int isinf_local(double x) { 
#ifdef __INTEL_COMPILER
  return isinf(x);
#else
  return std::isinf(x);
#endif
}


int myChk(double a){
  std::cerr<<"val is: "<<a <<"\t";
  if(isnan_local(a))
    std::cerr<<"program says isnan";
  if(isinf_local(a))
    std::cerr<<"program says isinf";
  std::cerr<<"\n";
  return 0;
}

int main(){
  double a …
Run Code Online (Sandbox Code Playgroud)

c c++ math function

37
推荐指数
6
解决办法
4万
查看次数

重复使用浮动缓冲区,但没有未定义的行为

在一个特定的C++函数中,我碰巧有一个指向浮点缓冲区的指针,我想暂时用它来存储一半的双精度数.有没有一种方法可以使用此缓冲区作为临时空间来存储双打,这也是标准允许的(即,不是未定义的行为)?

总之,我想这样:

void f(float* buffer)
{
  double* d = reinterpret_cast<double*>(buffer);
  // make use of d
  d[i] = 1.;
  // done using d as scratch, start filling the buffer
  buffer[j] = 1.;
}
Run Code Online (Sandbox Code Playgroud)

据我所知,没有简单的方法可以做到这一点:如果我理解正确,reinterpret_cast<double*>这样会因为类型别名而导致未定义的行为,并且memcpyunion不复制数据和分配额外空间的情况下无法使用浮点数/双数,这会失败在我的情况下,目的并且碰巧是昂贵的(并且在C++中不允许使用用于类型惩罚的联合).

可以假设浮动缓冲区已正确对齐以将其用于双精度.

c++ strict-aliasing type-punning

25
推荐指数
2
解决办法
945
查看次数

什么是将一个浮点数类型化为int的正确方法,反之亦然?

下面的代码通过一些位攻击执行快速反平方根操作.该算法可能是由Silicon Graphics在1990年代早期开发的,它也出现在Quake 3中. 更多信息

但是我从GCC C++编译器收到以下警告:解除引用类型惩罚指针将破坏严格别名规则

我应该使用static_cast,reinterpret_cast还是dynamic_cast在这种情况下使用?

float InverseSquareRoot(float x)
{
    float xhalf = 0.5f*x;
    int32_t i = *(int32_t*)&x;
    i = 0x5f3759df - (i>>1);
    x = *(float*)&i;
    x = x*(1.5f - xhalf*x*x);
    return x;
}
Run Code Online (Sandbox Code Playgroud)

c++ strict-aliasing gcc-warning undefined-behavior type-punning

24
推荐指数
4
解决办法
6830
查看次数

什么时候c ++ 11中的类型允许记忆?

我的问题如下:

如果我想复制类类型,memcpy可以非常快速地完成.在某些情况下允许这样做.

我们有一些类型特征:

  • is_standard_layout.
  • is_trivially_copyable.

我想知道的是当类型是"可按位复制"时的确切要求.

我的结论是,如果两个is_trivally_copyableis_standard_layout特征都为真,则类型是按位可复制的:

  1. 这正是我需要按位复制的内容吗?
  2. 是否过度约束?
  3. 它不受约束吗?

PS:当然,memcpy的结果必须正确.我知道我可以在任何情况下记忆,但不正确.

c++ memory c++11

23
推荐指数
4
解决办法
2889
查看次数

C++ 是否保证具有单个平凡成员的“平凡”结构具有相同的二进制布局?

我们的项目中有一些严格类型的整数类型:

struct FooIdentifier {
  int raw_id; // the only data member

  // ... more shenanigans, but it stays a "trivial" type.
};

struct BarIdentifier {
  int raw_id; // the only data member

  // ... more shenanigans, but it stays a "trivial" type.
};
Run Code Online (Sandbox Code Playgroud)

基本上是这里提出的或类似于Unit Library 中使用的东西。

除了类型系统之外,这些结构基本上都是整数。

我的问题在这里现在是:有没有C ++语言保证这些类型奠定了相当于100%的内存作为一个经常int会是什么?

注意:由于我可以静态检查类型是否具有相同的大小(即没有填充),我真的只对无意外填充的情况感兴趣。我应该从一开始就添加这个注释

// Precodition. If platform would yield false here, I'm not interested in the result.
static_assert(sizeof(int) == sizeof(ID_t)); …
Run Code Online (Sandbox Code Playgroud)

c++ memory-layout language-lawyer

18
推荐指数
3
解决办法
1039
查看次数

C别名规则和memcpy

在回答另一个问题时,我想到了以下示例:

void *p;
unsigned x = 17;

assert(sizeof(void*) >= sizeof(unsigned));
*(unsigned*)&p = 17;        // (1)
memcpy(&p, &x, sizeof(x));  // (2)
Run Code Online (Sandbox Code Playgroud)

第1行打破了别名规则.然而,第2行是好的.别名规则.问题是:为什么?编译器是否具有关于memcpy等函数的特殊内置知识,还是有一些其他规则可以使memcpy正常运行?有没有办法在标准C中实现类似memcpy的函数而不破坏别名规则?

c c++ strict-aliasing

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

枚举类型布局是否与其基础类型兼容?

我期待通过n3690,即将到来的选秀C++14标准,我在看节7.29

如果两个枚举类型具有相同的基础类型,则它们是布局兼容的。

但是,我找不到任何说明枚举类型与其基础类型布局兼容的内容。对我来说,考虑到“基础类型”的含义,这应该遵循合理的语义,这似乎很明显,但标准是否真的保证了这一点?

c++ enums language-lawyer c++14

5
推荐指数
1
解决办法
249
查看次数

为什么 std::memcpy (作为类型双关的替代方法)不会导致未定义的行为?

sizeof(double) char在寻找将s 组合到 a 的方法时double,我读了几篇文章,std::memcpy推荐使用以下方法:

char bytes[sizeof(double)];
// fill array
double d;
std::memcpy(&d, bytes, sizeof(double));
Run Code Online (Sandbox Code Playgroud)

但是,我想知道为什么进一步使用d可以定义行为。

如果它不是一个double,而是一个复杂的类对象,那么访问它肯定也不会被定义,不是吗?那么,为什么double.

编辑:为了使我的问题清楚,我想指定我的目标:我想找到一种方法将多个chars 组合成 adouble并进一步使用这个 double,而不会导致未定义的行为。我double希望指定 的值。无论如何,我认为这是不可能的,因为标准甚至没有说明任何有关大小的信息,更不用说double. 但是,我要求d一些有效的(即“可访问的”)double值。

c++ undefined-behavior language-lawyer

5
推荐指数
1
解决办法
639
查看次数