C硬编码数组作为memcpy参数

Fer*_*eak 38 c arrays hardcoded

我想传入一个硬编码的char数组作为sourcememcpy 的参数...像这样:

memcpy(dest, {0xE3,0x83,0xA2,0xA4,0xCB} ,5);
Run Code Online (Sandbox Code Playgroud)

使用clang编译时会出现以下错误:

cccc.c:28:14: error: expected expression
Run Code Online (Sandbox Code Playgroud)

如果我修改它(参见额外的括号):

memcpy(dest,({0xAB,0x13,0xF9,0x93,0xB5}),5);
Run Code Online (Sandbox Code Playgroud)

clang给出的错误是:

cccc.c:26:14: warning: incompatible integer to pointer
              conversion passing 'int' to parameter of
              type 'const void *' [-Wint-conversion]

cccc.c:28:40: error: expected ';' after expression
memcpy(c+110,({0xAB,0x13,0xF9,0x93,0xB5}),5);
Run Code Online (Sandbox Code Playgroud)

那么,问题是:

如何传入硬编码数组作为memcpy(http://www.cplusplus.com/reference/cstring/memcpy/)的源参数

我试过了:

(void*)(&{0xAB,0x13,0xF9,0x93,0xB5}[0])  - syntax error
{0xAB,0x13,0xF9,0x93,0xB5}               - syntax error
({0xAB,0x13,0xF9,0x93,0xB5})             - see above
(char[])({0xE3,0x83,0xA2,0xA4,0xCB})     - error: cast to incomplete type 'char []' (clang)
Run Code Online (Sandbox Code Playgroud)

和一些更疯狂的组合我很惭愧写在这里......

请记住:我希望创建一个新的变量来保存阵列.

Mik*_*CAT 41

如果使用C99或更高版本,则可以使用复合文字.(N1256 6.5.2.5)

#include <stdio.h>
#include <string.h>
int main(void){
    char dest[5] = {0};
    memcpy(dest, (char[]){0xE3,0x83,0xA2,0xA4,0xCB} ,5);
    for (int i = 0; i < 5; i++) printf("%X ", (unsigned int)(unsigned char)dest[i]);
    putchar('\n');
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

更新:这适用于GCC上的C++ 03和C++ 11,但是被-pedantic-errors选中拒绝.这意味着这不是标准C++的有效解决方案.

#include <cstdio>
#include <cstring>
int main(void){
    char dest[5] = {0};
    memcpy(dest, (const char[]){(char)0xE3,(char)0x83,(char)0xA2,(char)0xA4,(char)0xCB} ,5);
    for (int i = 0; i < 5; i++) printf("%X ", (unsigned int)(unsigned char)dest[i]);
    putchar('\n');
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

要点是:

  • 使数组const,或取得临时数组的地址将被拒绝.
  • char明确地转换数字,或者缩小转换将被拒绝.

  • 有趣的OP似乎尝试过这个 - 但是使用C++编译器. (5认同)

Iga*_* S. 24

您只需发送一个字符串作为参数.它似乎编译得很好.

#include <iostream>
#include <string.h>
using namespace std;

int main() {
    char dest[6] = {0};
    memcpy(dest,"\XAB\x13\XF9\X93\XB5", 5);

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

  • @MikhailT."\ 0"和"0"之间的区别在哪里?它们都为我编译为相同的"0"值. (3认同)
  • @NateEldredge:不会'strcpy`复制尾随的null吗? (2认同)

Lun*_*din 18

最好的解决方案根本不是这样做,而是使用临时变量:

const char src[] = {0xE3,0x83,0xA2,0xA4,0xCB};
memcpy(dest, src, sizeof(src));
Run Code Online (Sandbox Code Playgroud)

这段代码是最易维护的,因为它不包含任何"幻数",所以它不会包含任何丢失的数组项或数组输出错误,就像复合文字版本一样.

此代码也与C++和C90兼容.

这里最重要的是要意识到生成的机器代码无论如何都是相同的.不要以为使用复合文字进行任何形式的优化.

  • @ user1717828任何形式的工程中最重要的任务之一是质疑规范,特别是当它没有任何意义时.在这种情况下,规范(OP)表明海报可能不知道变量在内存中的分配方式或编译器优化的工作方式.因此,重要的是发布一个"反答案",否则初学者可能会阅读这篇文章并认为问题中的"无变量"要求是有道理的,然后开始相应地混淆他们的代码,通过垃圾邮件发送复合文字. (12认同)
  • @ user1717828好吧,为了论证的缘故,我会说说某些东西在特定的边缘情况下不起作用并且说他们根本不想这样做之间存在差异.据我所知,这个问题就是后者.并且经常 - 并非总是,但经常 - 当有人说"我不想做X"时,他们真的应该做X,他们只是错误或误导他们认为他们不应该这样做的原因不这样做. (9认同)
  • 认为我们应该信任一份声明,因为他们来自一个13K的用户,这是合理的谬误"权威论证".仅仅因为在任何领域有良好声誉的人提出索赔并不意味着他们是对的. (6认同)
  • @DavidZ你是对的,但是从一个13K的用户我认为"我不想做X"是一个我们可以信赖的句子. (4认同)
  • -1,OP明确表示他不想在原帖中这样做.建议某人在他们明确表示在他们的边缘案件中不起作用之后以"正确"的方式做某事会破坏核心问题. (3认同)
  • @LP这是一个合理的观点,但我并不是真的同意 - 如果我用这样的句子问一个问题,我不建议甚至相信自己.如果有一个明显的解决方案并且提问者不想使用它,他们应该在问题中给出某种理由.(只是"教育目的"很好,但只是"我不想"对我来说不是.)否则我认为回答他们应该做他们不想做的事情是合法的,如果这就是你真正认为的正确答案. (3认同)
  • @CoolGuy`memcpy(dest,(char []){0xE3,0x83,0xA2,0xA4,0xCB},5);`< - 这是神奇的数字.你不能在复合文字上使用`sizeof`.好吧,你可以,如果你使用宏,这可能是最糟糕的选择:`#define COMPOUND(char []){0xE3,0x83,0xA2,0xA4,0xCB}```memcpy(dest, &COMPOUND,sizeof(COMPOUND));`与使用普通的const变量相比,它只是一个完全脑损伤的解决方案. (3认同)

LPs*_*LPs 10

您可以使用复合文字.

int main()
{
    unsigned char dest[5];
    size_t i;

    memcpy(dest, (unsigned char[]){0xE3,0x83,0xA2,0xA4,0xCB} ,5);

    printf("Test: " );
    for(i=0; i<sizeof(dest)/sizeof(dest[0]); i++)
        printf("%02X - ", dest[i] );
    printf("\n");
    return 0;
}
Run Code Online (Sandbox Code Playgroud)