小编Jac*_*aib的帖子

2 个经过“restrict”修饰的指针可以比较相等吗?

int foo(void *restrict ptr1, void *restrict ptr2)
{
  if (ptr1 == ptr2) {
    return 1234;
  } else {
    return 4321;
  }
}
Run Code Online (Sandbox Code Playgroud)

restrict意味着指针指向的内存没有被任何其他指针别名。鉴于此,thenptr1ptr2不能指向同一区域,因此比较是同义反复,并且在所有情况下都foo()应该返回。4321

然而clanggcc不要这样看(https://godbolt.org/z/fvPd4a1vd)。这是错过的优化还是有其他原因?

c c++ compiler-optimization language-lawyer restrict-qualifier

17
推荐指数
2
解决办法
849
查看次数

非零退出编译器提示

长话短说:我想要

int some_opaque_error_handler() __attribute__((returns_nonzero));
                                ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^ equivalent of this
Run Code Online (Sandbox Code Playgroud)

我使用的基于 AC/C++ 的库使用返回码来指示错误,这会导致编译器抱怨使用“统一”值。例如

int some_opaque_error_handler() __attribute__((returns_nonzero));
                                ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^ equivalent of this
Run Code Online (Sandbox Code Playgroud)

在这种情况下,如果返回错误,则*p永远不会访问它,但由于错误处理程序是不透明的,编译器无法知道这一点。bar()foo()

无论如何,是否有办法让编译器知道通过错误处理程序返回的结果几乎总是[1] 非零(因此任何后续访问都不会发生?)[2]。我在运行静态分析器时遇到类似的问题,因为它们也假设执行可能会继续经过这些点。


[1]用户可以将错误处理程序的行为更改为(尽管不太可能)返回,0因此任何解决方案/编译器提示都必须是非绑定的。

[2]是的,我知道我可以简单地初始化变量(这就是我目前所做的),但是:

  1. 此类案例有大量的公制数量
  2. 这些警告似乎严重依赖于编译器、编译器版本、优化级别以及土星环相对于银河平面的方向

所以这感觉就像是一场赢不了的打地鼠游戏

c c++ compiler-warnings

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

编译器是否内联?

众所周知,编译器工具带中最强大的工具是将函数内联到其调用站点中。但如果反过来呢?如果是的话,完成了吗?什么时候?例如给出:

void foo(int x)
{
  auto y = bar(x);
  baz(y);
}

void bop()
{
  int x;
  auto y = bar(x);
  baz(y);
}
Run Code Online (Sandbox Code Playgroud)

编译器将其抽象为是否有意义

void qux(int x)
{
  auto y = bar(x);
  baz(y);
}

void foo(int x)
{
  qux(x);
}

void bop()
{
  int x;
  qux(x);
}
Run Code Online (Sandbox Code Playgroud)

c++ compiler-construction optimization

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

使用每个条目实例变量删除列表中重复项的最快方法

TL; 博士

有没有更快的方法

listOfClasses = [fooA, fooB, fooC]
setOfStrings = {c.string for c in listOfClasses}
newListOfClasses = []
for c in listOfClasses:
  if c.string in setOfStrings:
    newListOfClasses.append(c)
    setOfStrings.remove(c.string)
Run Code Online (Sandbox Code Playgroud)

限制/警告:

  • listOfClasses

    • 条目不一定是唯一的,可能包含重复的类
    • 条目数量通常在 3-4 个左右,但可以多达 ~20 个
  • newListOfClasses

    • 不能创建新类,它必须使用相同的对象(这些对象不是我的,我不知道它们是如何初始化的,所以我不知道它们里面除了字符串之外是什么)。
    • 结果必须至少是可迭代的
    • 结果顺序无关紧要
    • 可以覆盖原来的 listOfClasses

假设我有一堂课

class Foo(object):
  def __init__(self,string):
    self.string = string
Run Code Online (Sandbox Code Playgroud)

以及我想删除所有具有重复“字符串”实例变量的类的类列表

fooA = Foo("alice")
fooB = Foo("alice")
fooC = Foo("His Royal Highness The Prince Philip, Duke of Edinburgh, Earl of Merioneth, Baron Greenwich, Royal Knight of the Most …
Run Code Online (Sandbox Code Playgroud)

python performance list-comprehension list python-3.x

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

将 C Cast 宏转换为 C++ 函数

我正在使用一个使用通常的 C“继承”技巧的 C 库

typedef struct Base_ *BasePointer;
struct Base_ {
};

typedef struct Derived_ *DerivedPointer;
struct Derived_ {
  Base_ header;
};

#define BaseCast(obj) ((BasePointer)(obj))

void bar(BasePointer);

void foo(DerivedPointer derived)
{
  bar(BaseCast(derived));
}
Run Code Online (Sandbox Code Playgroud)

我正在编写一些 C++ 实用程序,其中一个实用程序是一种更安全的实用程序,BaseCast()使用类型特征来检查对象是否确实是派生的。这BaseCast()必须与宏完全互换。我有以下内容,但是可以做得更好吗?

// convertible_to_base checks for existence of object->header
// and that object->header is of type Base_

template <typename T>
[[nodiscard]] static inline constexpr BasePointer& BaseCast(T& object) noexcept
{
  static_assert(util::convertible_to_base<T>::value, "");
  return reinterpret_cast<BasePointer&>(object);
}

template <typename T>
[[nodiscard]] static inline constexpr …
Run Code Online (Sandbox Code Playgroud)

c++

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