Перейти к содержанию
    

Приведение типов в Си

On 7/17/2023 at 11:14 PM, jcxz said:

Ведь варнингов нет.

Quote

$ arm-unknown-eabi-gcc -fanalyzer 1.c
1.c: In function 'main':
1.c:5:14: warning: stack-based buffer overflow [CWE-121] [-Wanalyzer-out-of-bounds]
    5 |   *(int *)&c = 0x12345678;
      |   ~~~~~~~~~~~^~~~~~~~~~~~
  'main': events 1-2
    |
    |    3 |   char c;
    |      |        ^
    |      |        |
    |      |        (1) capacity: 1 byte
    |    4 |
    |    5 |   *(int *)&c = 0x12345678;
    |      |   ~~~~~~~~~~~~~~~~~~~~~~~
    |      |              |
    |      |              (2) out-of-bounds write from byte 1 till byte 3 but 'c' ends at byte 1
    |
1.c:5:14: note: write of 3 bytes to beyond the end of 'c'
    5 |   *(int *)&c = 0x12345678;
      |   ~~~~~~~~~~~^~~~~~~~~~~~

 

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

On 7/18/2023 at 1:21 AM, Arlleex said:

А можно мой?

Quote

$ arm-unknown-eabi-gcc -Wall 1.c
1.c: In function 'main':
1.c:9:12: warning: format '%d' expects argument of type 'int', but argument 2 has type 'uint32_t' {aka 'long unsigned int'} [-Wformat=]
    9 |   printf("%d", c);
      |           ~^   ~
      |            |   |
      |            int uint32_t {aka long unsigned int}
      |           %ld

 

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

У '+' порядок вычислений не определен, а для volatile это может выйти боком. IAR, кстати, об этом умеет рапортовать. На моей памяти только он.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

10 часов назад, sasamy сказал:

 

Это всего лишь частный случай, когда вы расположили переменную и обращение к ней в одном файле. Расположите в разных:

//в одном си-файле:
void f(char *p)
{
  *(int *)p = 0x12345678;
}

//в другом си-файле:
void f(char *p);
char cc;
...
f(&cc);  ///

чтобы в модуле компиляции, где находится f(), не было видно объявление cc.

Или как насчёт такого?:

///
char *ppp;
void f()
{
  char cc;
  ...
  ppp = &cc;
  ...
}
...
f();
*ppp = 123;

Варнинги есть?  :wink:

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

24 минуты назад, jcxz сказал:
//в одном си-файле:
void f(char *p)
{
  *(int *)p = 0x12345678;
}

//в другом си-файле:
void f(char *p);
char cc;
...
f(&cc);  ///

Справедливости ради ARM Compiler 6.12, все предупреждения включены

Цитата

warning: cast from 'char *' to 'int *' increases required alignment from 1 to 4 [-Wcast-align]

Да и в любом случае GCC уж точно предупредит о нарушении улицы рощи строгих сглаживаний strict aliasing.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

On 7/18/2023 at 1:49 AM, Arlleex said:

Эх, глупый GCC, а баг то не и увидел!

а там есть баг ? UB и то только начиная с с11

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Только что, sasamy сказал:

а там есть баг ? UB и то только начиная с с11

UB == баг, в любом случае. Если было бы неуточняемое поведение, то это другое.

Насчет C11 не знаю, когда оно действительно появилось. Но, ИМХО, должно было весьма давно.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

On 7/18/2023 at 10:54 AM, jcxz said:

Это всего лишь частный случай

статический анализатор встроенный в gcc тоже частный случай - есть и внешние для взрослых

On 7/18/2023 at 11:35 AM, Arlleex said:

UB == баг, в любом случае.

это в Rust, в С - нет

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

12 минут назад, Arlleex сказал:

Справедливости ради ARM Compiler 6.12, все предупреждения включены

Но это предупреждение о выравнивании. А выход за пределы остался незамеченным.

А если так:

//в одном си-файле:
typedef __packed u32 u32p8;
void f(char *p)
{
  *(u32p8 *)p = 0x12345678;
}

//в другом си-файле:
void f(char *p);
char cc;
...
f(&cc);

то и варнинга о выравнивании видимо не будет (не знаю есть ли там __packed, если нет - то его аналог).

 

Кроме того - это только для ARM-компиляторов. Коими мир не ограничивается. Есть и другие системы, где о выравнивании и не слыхивали.  :wink:

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

1 минуту назад, sasamy сказал:

это в Rust, в С - нет

Приведите пример, когда нет.

Стандарт четко формулирует понятие UB, и на то оно UB, чтобы не гарантировать вообще ничего.

UB в одном месте запросто может перескочить чуть дальше по коду, выкинуть что-то правильное и добавить не правильного. Как карта ляжет.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

On 7/18/2023 at 11:41 AM, Arlleex said:

Приведите пример, когда нет.

так вы его сами привели - кроме IAR никто это ошибкой не считает

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

12 минут назад, jcxz сказал:

то и варнинга о выравнивании видимо не будет (не знаю есть ли там __packed, если нет - то его аналог).

__unaligned в моем случае, т.к. __packed это для структур. Все равно warning есть...
 

6 минут назад, sasamy сказал:

так вы его сами привели - кроме IAR никто это ошибкой не считает

А Вы не согласны, что неупорядоченный доступ к volatile-объектам - это не норма? Тогда мне нечего на это ответить.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
К сожалению, ваш контент содержит запрещённые слова. Пожалуйста, отредактируйте контент, чтобы удалить выделенные ниже слова.
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...