2016-02-11 3 views
1

Я где-то видел этот код, это не целочисленное переполнение и неопределенное поведение?, является ли этот код целым числом переполнения

предположить 0 < str[i] < 127

char *msl_decrypt(char *str) { 
    char *decrypted; 
    unsigned int i; 
    int key = 0xFACA; 

    for (i = 0; i < strlen(str); ++i) { 
     str[i] = str[i] + key; // referring to this line, is it UB? 
    } 
    ... 
+0

И ответ: возможно! – Olaf

+0

@Olaf Никакие беззнаковые целые числа не являются частью рассматриваемого расчета. –

+0

Если что-то это переполнение байта, так как 'str [i]' имеет тип 'char' – RPGillespie

ответ

6

Жаль, что вы не указали целевые параметры. Таким образом, для следующего я полагаю:

  • CHAR_BIT == 8
  • sizeof(int) >= 2
  • не обивка биты
  • str указует на действительные и инициированные памяти, правильно nul -завершённые и не больше, чем INT_MAX (в качестве альтернативы использовать size_t для index - thanks @chux).
  • и, возможно, другие предпосылки, которые мы склонны принимать за данные.

Это типичные для большинства современных реализаций.

Для sizeof(int) == 2 инициализатор представляет собой поведение, определенное реализацией, поскольку в качестве инициализатора используется константа unsigned int. Для более широких int это нормально. Вещи также усложняются, если (int)(0xFACA) + CHAR_MAX > INT_MAX (арифметически, также относится только к 2 байтам int).

Остальное зависит от реализации определенного поведения в более сложным образом:

1) Добавление str[i] + key: Здесь str[i] преобразуется в int во-первых, добавление сделано как int и дает int результат.

2) Назначение str[i] = ...: Здесь int результат сложения преобразуется в char. Для этого у нас есть два варианта, в зависимости от зарегистрированы ностей char (реализаций определенных):

  • без знака: Результат преобразуется в стандартном определенном способе unsigned char.
  • подписан: результат «вниз» преобразуется в «меньший» signed char в определенном порядке реализации. не

Итак: ненеопределенное поведение, но (и комментарии) показывает, сколько вы должны иметь в виду при использовании знаковых целых чисел в С.


Но:

Слишком много Выполнено определенное поведение, и требуется множество предварительных условий (которые довольно общий, хотя). Лучше использовать unsigned char и unsigned int на протяжении всего кода. Это сделает код стандартным и совместимым.Даже для значений, отличных от CHAR_BIT. Если вы полагаетесь на 8-битные значения, используйте uint8_t от stdint.h.

+0

Еще одно обязательное предположение заключалось в том, что 'int key = 0xFACA; 'генерирует' int', который не находится в пределах 127 от 'INT_MAX' –

+0

@MM: Да; Я также добавил, что (только в более общей форме). Но, пожалуйста, не просите удалить предварительные условия и сделать весь текст общим; Это происходит позже ;-). – Olaf

+0

, если вы можете немного уточнить, почему вы предположили, что эти предпосылки были бы хорошими. –

Смежные вопросы