Подтвердить что ты не робот

C жесткого кода как параметр memcpy

Я хочу передать массив hardcoded char в качестве параметра source для memcpy... Что-то вроде этого:

memcpy(dest, {0xE3,0x83,0xA2,0xA4,0xCB} ,5);

Скомпилированный с clang дает следующую ошибку:

cccc.c:28:14: error: expected expression

Если я изменяю его (см. дополнительную скобку):

memcpy(dest,({0xAB,0x13,0xF9,0x93,0xB5}),5);

ошибка, данная 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);

Итак, вопрос:

Как передать массив hardcoded в качестве исходного параметра 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)

и еще несколько безумных комбинаций, которые мне стыдно писать здесь...

Помните: я НЕ хочу создать новую переменную для хранения массива.

4b9b3361

Ответ 1

Если вы используете 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;
}

UPDATE: Это работало для С++ 03 и С++ 11 на GCC, но отклонено с помощью опции -pedantic-errors. Это означает, что это не является допустимым решением для стандартного С++.

#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;
}

:

  • Сделать массив const или принять адрес временного массива.
  • Ввести числа до char явно, или сужение преобразования будет отклонено.

Ответ 2

Вы можете просто отправить строку в качестве параметра. Кажется, что компилировать просто отлично.

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

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

    return 0;
}

Ответ 3

Лучшее решение - не делать этого вообще, а использовать временную переменную:

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

Этот код наиболее удобен в обслуживании, потому что он не содержит "магических чисел", поэтому он не будет содержать недостающих элементов массива или массивов, как это делает сложная буквальная версия.

Этот код также совместим с С++ и C90.

Самое главное здесь - понять, что сгенерированный машинный код будет в любом случае идентичным. Не думайте, что вы делаете какую-либо форму оптимизации, используя сложные литералы.

Ответ 4

Вы можете использовать сложные литералы.

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;
}