标签: function-attributes

不同编译器中的pure/const函数属性

pure是一个函数属性,表示函数不会修改任何全局内存.
const是一个函数属性,表示函数不读取/修改任何全局内存.

鉴于该信息,编译器可以进行一些额外的优化.

GCC示例:

float sigmoid(float x) __attribute__ ((const));

float calculate(float x, unsigned int C) {
    float sum = 0;
    for(unsigned int i = 0; i < C; ++i)
        sum += sigmoid(x);
    return sum;
}

float sigmoid(float x) { return 1.0f / (1.0f - exp(-x)); }
Run Code Online (Sandbox Code Playgroud)

在该示例中,编译器可以将函数计算优化为:

float calculate(float x, unsigned int C) {
    float sum = 0;
    float temp = C ? sigmoid(x) : 0.0f;
    for(unsigned int i = 0; i < C; ++i)
        sum …
Run Code Online (Sandbox Code Playgroud)

c++ gcc const function-attributes

32
推荐指数
2
解决办法
8710
查看次数

如何在C++ 11可变参数模板中使用GCC的printf格式属性?

我有一个C++类,它是日志系统的前端.它的日志记录功能是使用C++ 11的可变参数模板实现的:

template <typename... Args>
void Frontend::log(const char *fmt, Args&&... args) {
  backend->true_log(fmt, std::forward<Args>(args)...);
}
Run Code Online (Sandbox Code Playgroud)

每个日志记录后端都实现自己的版本true_log,除其他外,它使用转发的参数进行调用vsnprintf.例如:

void Backend::true_log(const char *fmt, ...) {
  // other stuff..
  va_list ap;
  va_start(ap, fmt);
  vsnprintf(buffer, buffer_length, fmt, ap);
  va_end(ap);
  // other stuff..
}
Run Code Online (Sandbox Code Playgroud)

一切都很好,我很高兴.

现在,我想对log()参数添加静态检查:具体来说,我想使用GCC的printf格式属性.

我开始使用标记log()函数__attribute__ ((format (printf, 2, 3)))(因为this第一个"隐藏"参数,我需要将参数索引移动一个).这不起作用,因为如果失败并出现编译错误:

error: args to be formatted is not ‘...’
Run Code Online (Sandbox Code Playgroud)

然后,我尝试将相同的属性添加到该true_log()函数中.它编译,但实际上没有执行错误检查:我试图传递log()一些无效的格式/变量组合,并且没有发出警告.也许这种检查"太晚了",换句话说,有关变量的信息已经在调用链中丢失了?

作为最后的手段,如果我注释log()__attribute__ ((format (printf, 2, 0))),我会收到关于错误的格式字符串警告,但无诊断会为无效的格式/变量组合发出.

总结问题: …

c++ gcc function-attributes variadic-templates c++11

15
推荐指数
2
解决办法
3143
查看次数

每个模板实例化的 GCC/Clang 函数属性

我有一些手工向量化的 C++ 代码,我正在尝试通过函数多版本化制作可分发的二进制文件。由于代码对不同指令集(SSE2、AVX2、AVX512)使用 SIMD 内在函数,因此它使用模板专业化来决定使用哪些内在函数。

整体结构大致如下:

template <unsigned W, unsigned N> struct SIMD {};  // SIMD abstraction

template <> struct SIMD<128, 8> {  // specialization for specific dimensions
  using Vec = __m128i;
  static always_inline Vec add(Vec a, Vec b) { return _mm_add_epi8(a, b); }
  ...  // many other SIMD methods
};

... // many other dimension specializations for different instruction sets

template <unsigned W, unsigned N> class Worker {
  void doComputation(int x) {
    using S = SIMD<W, N>;
    ... // …
Run Code Online (Sandbox Code Playgroud)

c++ gcc clang template-specialization function-attributes

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

在模块中初始化变量的最佳方法?

假设我需要将传入数据写入云上的数据集。我何时、何地以及是否需要在代码中使用数据集,取决于传入的数据。我只想获取对数据集的引用一次。实现这一目标的最佳方法是什么?

  1. 启动时初始化为全局变量并通过全局变量访问

    if __name__="__main__":
        dataset = #get dataset from internet
    
    Run Code Online (Sandbox Code Playgroud)

这看起来是最简单的方法,但即使从不需要它也会初始化该变量。

  1. 第一次需要数据集时获取引用,保存在全局变量中,并通过get_dataset()方法访问

    dataset = None
    
    def get_dataset():
        global dataset
        if dataset is none
            dataset = #get dataset from internet
        return dataset
    
    Run Code Online (Sandbox Code Playgroud)
  2. 第一次需要数据集时获取参考,保存为函数属性,并通过get_dataset()方法访问

    def get_dataset():
        if not hasattr(get_dataset, 'dataset'):
            get_dataset.dataset = #get dataset from internet
        return get_dataset.dataset
    
    Run Code Online (Sandbox Code Playgroud)
  3. 任何其他方式

python initialization global-variables function-attributes

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

Objective C中的不可用属性是什么意思?

Objective C中的不可用属性有什么作用?

__attribute__((unavailable("message")))
Run Code Online (Sandbox Code Playgroud)

Clang中有这个和其他属性的在线参考吗?

objective-c clang function-attributes

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

装饰器设置功能的属性

我希望只有登录用户具有所需的权限级别才能执行不同的功能.

为了让我的生活更复杂,我只想使用装饰器.下面我尝试permission在'装饰'功能上设置属性- 如下所示.

def permission(permission_required):
    def wrapper(func):
        def inner(*args, **kwargs):
            setattr(func, 'permission_required', permission_required)
            return func(*args, **kwargs)
        return inner
    return wrapper

@permission('user')
def do_x(arg1, arg2):

    ...

@permission('admin')
def do_y(arg1, arg2):
    ...
Run Code Online (Sandbox Code Playgroud)

但当我这样做时:

fn = do_x
if logged_in_user.access_level == fn.permission_required:
    ...
Run Code Online (Sandbox Code Playgroud)

我收到一个错误 'function' object has no attribute 'permission_required'

我错过了什么?

python attributes decorator function-attributes python-decorators

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

函数属性returns_twice

我只是查找gcc的funciton属性(http://gcc.gnu.org/onlinedocs/gcc-4.7.2/gcc/Function-Attributes.html)并遇到了该returns_twice属性.

而且我绝对无能为力,在什么情况下函数可以返回两次...我快速查阅了所提到的内容vfork(),setjmp()但仍然不知道一个适用的场景是什么样的 - 你们中的任何人使用它还是可以解释一下?

c c++ function function-attributes

7
推荐指数
2
解决办法
1201
查看次数

重新分配一个函数属性使其"无法访问"

我有一个简单的小装饰器,它将函数调用的结果缓存dict为函数属性.

from decorator import decorator
def _dynamic_programming(f, *args, **kwargs):
    try:
        f.cache[args]
    except KeyError:
        f.cache[args] = f(*args, **kwargs)
    return f.cache[args]

def dynamic_programming(f):
    f.cache = {}
    return decorator(_dynamic_programming, f)
Run Code Online (Sandbox Code Playgroud)

我现在想添加清空缓存的可能性.所以我改变了dynamic_programming()这样的功能:

def dynamic_programming(f):
    f.cache = {}
    def clear():
        f.cache = {}
    f.clear = clear
    return decorator(_dynamic_programming, f)
Run Code Online (Sandbox Code Playgroud)

现在让我们假设我使用这个小东西来实现Fibonacci数函数:

@dynamic_programming
def fib(n):
    if n <= 1:
        return 1
    else:
        return fib(n-1) + fib(n-2)

>>> fib(4)
5
>>> fib.cache
{(0,): 1, (1,): 1, (2,): 2, (3,): 3, (4,): 5}
Run Code Online (Sandbox Code Playgroud)

但是现在当我清除缓存时会发生一些奇怪的事情:

>>> …
Run Code Online (Sandbox Code Playgroud)

python function-attributes

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

__attribute((const))的gcc行为不一致

我在gcc中遇到了一个非常奇怪的行为,关于运算符和标记的函数__attribute((const)).逻辑和算术运算符导致不同的优化,我不明白为什么.

这不是一个真正的错误,因为__attribute((const))它只是一个暗示并且不能保证其效果,但这仍然是非常令人惊讶的.有人有任何解释吗?

这是代码.所以我定义了一个__attribute((const))函数:

int f(int & counter) __attribute((const));
int f(int & counter) {
    ++counter;
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

然后我定义了一个运算符测试宏.这是通过宏而不是模板/仿函数来完成的,以便向编译器提供简单的代码并简化优化:

int global = 0; // forces results to be computed

#define TestOp(OP) \
    { \
        int n = 0; \
        global += (f(n) OP f(n)); \
        std::cout << "op" #OP " calls f " << n << " times" << std::endl; \
    }
Run Code Online (Sandbox Code Playgroud)

最后,我按如下方式测试不同的运算符.注释与输出g++-4.8 -std=c++11 -O2 -Wall -pedantic相同,输出为-O3-Ofast

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

c++ gcc compiler-optimization function-attributes

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

asmlinkage 是堆栈还是寄存器?

在大多数语言中,C 包括堆栈用于函数调用。这就是如果您在递归时不小心会收到“堆栈溢出”错误的原因。(不是双关语)。

如果这是真的,那么asmlinkageGCC 指令有什么特别之处。

它说,来自#kernelnewbies

asmlinkage 标签是我们应该注意的关于这个简单函数的另一件事。这是一些 gcc 魔法的 #define,它告诉编译器该函数不应期望在寄存器中找到它的任何参数(一种常见的优化),而只能在 CPU 的堆栈上。

我的意思是我不认为寄存器用于正常的函数调用

更奇怪的是,当你了解到它是在 x86 上使用 GCC regparm 函数属性实现的。

regparm的文档如下:

在 x86-32 目标上,如果参数在寄存器 EAX、EDX 和 ECX 中而不是在堆栈中是整数类型,则 regparm 属性会导致编译器将第一个参数传递给 number。

这基本上与asmlinkage正在尝试做的相反。

那么会发生什么?它们是在堆栈上还是在寄存器上。

我哪里错了?

信息不是很清楚。

linux x86 gcc linux-kernel function-attributes

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

std :: thread(c ++ 11)中使用的函数是否有[[noreturn]]?

因为std::thread t(foo);,有一个有意义foo [[noreturn]] () {...}吗?对于前者 对于一个分离的线程(在应用程序完成之前用作一种守护进程)?

c++ function-attributes c++11

-4
推荐指数
1
解决办法
194
查看次数