Jump to content

    
inventor

Странный стиль работы компилятора

Recommended Posts

 

uint8_t buf[32] = "abcdefgh";

 

почему можно и так?

uart_tx_buf(uart1, &buf, strlen(buf));

и так? 

uart_tx_buf(uart1, buf, strlen(buf));

вроде второй вариант выглядит более верно?

Share this post


Link to post
Share on other sites
12 minutes ago, Forger said:

 

А как выглядит прототип uart_tx_buf?

и что там внутри


Небось там uart_tx_buf( ...., void * ptr, ....), иначе компилятор заругается матом

нет, принимает u8* как второй параметр. не void*

   

static char buf[512];
    va_list list;
    int l = 0;  

    xSemaphoreTake(log_mtx, portMAX_DELAY);

*****


    HAL_UART_Transmit(uart, &buf, strlen(buf), 1000);
    HAL_UART_Transmit(uart, "\n\r", 2, 1000);

IAR:     Error[Pe167]: argument of type "char (*)[512]" is incompatible with parameter of type "uint8_t *"   log_utils.c    61 

 

Eclipse:   18:19:56 Build Finished. 0 errors, 10 warnings. (took 3s.445ms)

 

И как правильно?

адрес и buf и &buf одинаковый

почему компиляторы по разному это воспринимают?

 

int main()
{
    char buf[32];

    printf("addr &buf: %p\r\n", &buf);
    printf("addr buf:  %p\r\n", buf);
    return 0;
}
addr &buf: 0019FF1C
addr buf:  0019FF1C
 

Share this post


Link to post
Share on other sites
22 minutes ago, inventor said:

почему компиляторы по разному это воспринимают?

Потому что по сути это - разные вещи.

Правильно будет :

uart_tx_buf(uart1, &buf[0], strlen(buf));

или

uart_tx_buf(uart1, buf, strlen(buf));

 

Учите матчасть, в частности С ;)

Share this post


Link to post
Share on other sites
22.06.2021 в 18:36, Forger сказал:

Потому что по сути это - разные вещи.

Правильно будет :

uart_tx_buf(uart1, &buf[0], strlen(buf));

или

uart_tx_buf(uart1, buf, strlen(buf));

 

Учите матчасть, в частности С ;)

Это я понимаю, не понятно почему говногцц не даёт в этом месте ошибку

 

Имя массива - это указатель на адрес его первого элемента. Да, это именно так, данный факт следует принять как аксиому. Вы можете убедиться в этом выполнив такое выражение: printf("%p = %p\n", arrI, &arrI); Отсюда следует, что имя массива – это ничто иное, как указатель. (Хотя это немного особенный указатель, о чем будет упомянуто ниже.) (С)

Share this post


Link to post
Share on other sites
4 minutes ago, inventor said:

Это я понимаю, не понятно почему говногцц не даёт в этом месте ошибку

Мой компилятор ругается на несоответствие типов, кроме случае, если ожидает void *

Share this post


Link to post
Share on other sites
1 час назад, inventor сказал:

адрес и buf и &buf одинаковый

почему компиляторы по разному это воспринимают?

Адрес одинаковый, но типы разные. ИАР об этом и говорит.
По стандарту имя массива является адресом его первого элемента (одного).
buf = uint8_t * (указатель на байт)
&buf = char (*)[512] (указатель на массив из 512 байт)
Проверка типов это основа основ.

GCC видимо в данном случае позволяет больше вольности, что не есть хорошо.
 

Share this post


Link to post
Share on other sites
59 минут назад, inventor сказал:

Имя массива - это указатель на адрес его первого элемента

Неправильно.

Имя массива является указателем на его первый элемент. А не на адрес первого элемента. Ибо указатель на адрес чего-либо - это уже указатель на указатель.

Подробней тут.

Share this post


Link to post
Share on other sites
36 минут назад, inventor сказал:

А если так передать: &0[buf]...

Тоже правильно. [] - бинарная операция, ей пофигу в каком порядке аргументы. Но устоялось именно &buf[0].

Share this post


Link to post
Share on other sites
3 часа назад, inventor сказал:

А если так передать:

&0[buf]

Что скажет компилятор?

Имя массива это адрес его первого элемента. Вот так правильно.

Имя массива, как и имя переменной, не могут начинаться с цифры.

Share this post


Link to post
Share on other sites
3 часа назад, Xenia сказал:

Имя массива, как и имя переменной, не могут начинаться с цифры.

А это не имя переменной, это целое число (Integer constant).

https://en.cppreference.com/w/c/language/operator_member_access

"By definition, the subscript operator E1[E2] is exactly identical to *((E1)+(E2))"

Share this post


Link to post
Share on other sites
15 часов назад, inventor сказал:

Отсюда следует, что имя массива  это ничто иное, как указатель.

Все неправы. Правильно будет: "имя массива может быть неявно приведено к указателю на его первый элемент". Когда-то очень давно Александр Редчук очень подробно расписывал разницу, но сейчас уже не вспомню даже - на каком из форумов.

Добавлено: все-таки на этом форуме: 

Почитайте, интересно.

Share this post


Link to post
Share on other sites
17 hours ago, inventor said:

Это я понимаю, не понятно почему говногцц не даёт в этом месте ошибку

Особенно непонятно, что говногцц предупреждение в этом месте таки выдаёт: https://godbolt.org/z/oKx4djrcr

Share this post


Link to post
Share on other sites
13 hours ago, Xenia said:

Имя массива, как и имя переменной, не могут начинаться с цифры.

так можно, хотя и вид не очень понятный

int a[20];

a[0] = 1;

1[a] = 2;

2[a] = 3;

итд

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.