在函数中使用指针的临时值

Using temp value for pointer in function

我查看了 microchip 的 AES 示例。他们编写了以下代码段:

bool AES_encrypt(uint8_t * plaintext, uint8_t * ciphertext, uint8_t * key)
{
    bool encrypt_ok;

    uint8_t * temp_key = key;
    for(uint8_t i = 0; i < AES_BLOCK_LENGTH; i++){
        AES.KEY =  *(temp_key++);
}

为什么他们将指针复制到一个临时变量中?我用 Atmel studio 和反汇编程序验证了它,这两个案例

bool AES_encrypt(uint8_t * plaintext, uint8_t * ciphertext, uint8_t * key)
{
    bool encrypt_ok;

    /* Load key into AES key memory. */
    uint8_t * temp_key = key;
    for(uint8_t i = 0; i < AES_BLOCK_LENGTH; i++){
        AES.KEY =  *(temp_key++);
}   

bool AES_encrypt(uint8_t * plaintext, uint8_t * ciphertext, uint8_t * key)
{
    bool encrypt_ok;

    /* Load key into AES key memory. */
    for(uint8_t i = 0; i < AES_BLOCK_LENGTH; i++){
        AES.KEY =  *(key++);
}

产生相同的汇编代码(-O1 选项)。那么这个符号的目标是什么?

正如您所注意到的,在优化的构建中没有任何性能优势或劣势,任何称职的编译器都会在优化的早期阶段将它们减少到几乎完全相同的 IR。

这可能只是一种风格选择,有些人觉得直接修改参数很混乱,他们更喜欢在整个函数中保持原样;双重如此,因为这是示例代码,所以它意味着所有级别的程序员都可以轻松理解。

这种方法的额外优势包括这样一个事实,即更容易添加引用原始值(可能是调试语句)的代码或在调试版本的调试器中检查原始值。

不修改函数调用的参数(即滥用它们作为局部变量)被认为是一种很好的做法。这大概就是使用临时变量temp_key的原因,因为这里指针自增:

AES.KEY =  *(temp_key++);

不会与改变指针目标的值混淆(这里的反对者可能已经这样做了)。这当然是常见的做法。

另请参阅此处的讨论:Using function arguments as local variables

正如您所观察到的,这对实际的汇编代码没有任何影响,因此他们决定遵循这种范式,这有助于保持复杂函数的概览。