Странное поведение модификации Objective C для отрицательных чисел

Ну, кроме вопросов о дублировании ...

... в Стандарте есть хотя бы одно больное место.

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

Мы видим, что на LiveWorkSpace используется следующая команда и пример:

// -std=c++11 -Wall -W -pedantic -O2

#include 

struct ForwardDeclared;

void throw_away(ForwardDeclared* fd) {
   delete fd;
}

struct ForwardDeclared {
   ~ForwardDeclared() {
      std::cout << "Hello, World!\n";
   }
};

int main() {
   ForwardDeclared* fd = new ForwardDeclared();
   throw_away(fd);
}

Диагноз:

Compilation finished with warnings:
 source.cpp: In function 'void throw_away(ForwardDeclared*)':
 source.cpp:6:11: warning: possible problem detected in invocation of delete operator: [enabled by default]
 source.cpp:5:6: warning: 'fd' has incomplete type [enabled by default] 
 source.cpp:3:8: warning: forward declaration of 'struct ForwardDeclared' [enabled by default]
 source.cpp:6:11: note: neither the destructor nor the class-specific operator delete will be called, even if they are declared when the class is defined

Разве вы не хотите поблагодарить ваших компилятор для предупреждения вас;)?

42
задан Dan Rosenstark 29 December 2012 в 18:27
поделиться

9 ответов

result = n % 3;
if( result < 0 ) result += 3;

Не выполняйте дополнительные операции с модификациями, как это предлагается в других ответах. Они очень дорогие и ненужные.

53
ответ дан 26 November 2019 в 23:36
поделиться

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

Например, , если n ограничено значением -1000..2000, тогда вы можете использовать выражение:

result = (n+1002) % 3;

Убедитесь, что максимум плюс ваша константа не переполнится при суммировании.

8
ответ дан 26 November 2019 в 23:36
поделиться

В C и Objective-C операторы деления и модуля выполняют усечение до нуля. a / b равно этаж (a / b) , если a / b> 0 , в противном случае это потолок (a / b) если a / b <0 . Всегда бывает так, что a == (a / b) * b + (a% b) ,

14
ответ дан 26 November 2019 в 23:36
поделиться

Если это будет поведение, и вы знаете, что это будет, то для m% n = r просто используйте r = n + r . Если вы не уверены, что здесь произойдет, используйте тогда r = r% n .

Изменить: Подводя итог, используйте r = (n + (m% n))% n

4
ответ дан 26 November 2019 в 23:36
поделиться

Я также ожидал положительного числа, но я нашел это из ISO / IEC 14882: 2003: Языки программирования - C ++, 5.6.4 (найдено в Статья в Википедии об операции модуля ):

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

4
ответ дан 26 November 2019 в 23:36
поделиться

Почему: потому что именно так определяется оператор mod в стандарте C (помните, что Objective-C является расширением C). Это сбивает с толку большинство людей, которых я знаю (например, меня), потому что это удивительно, и вы должны это помнить.

Что касается обходного пути: я бы использовал uncleo's.

1
ответ дан 26 November 2019 в 23:36
поделиться

JavaScript тоже делает то же самое. Пару раз меня это ловило. Думайте об этом как о отражении вокруг нуля, а не о продолжении.

1
ответ дан 26 November 2019 в 23:36
поделиться

Есть два варианта для остатка, и знак зависит от языка. ANSI C выбирает знак дивиденда. Я подозреваю, что именно поэтому вы видите, что Objective-C тоже делает это. См. Также статью в википедии .

0
ответ дан 26 November 2019 в 23:36
поделиться

У нас есть проблема с языком:

math-er-says: i take this number plus that number mod other-number
code-er-hears: I add two numbers and then devide the result by other-number
code-er-says: what about negative numbers?
math-er-says: WHAT? fields mod other-number don't have a concept of negative numbers?
code-er-says: field what? ...
  • математик в этих беседах говорит о том, чтобы делать математику в круговой числовой прямой. Если вы вычтите нижнюю часть, вы перейдете к вершине.
  • человек кода говорит об операторе, который вычисляет остаток.

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

7
ответ дан 26 November 2019 в 23:36
поделиться
Другие вопросы по тегам:

Похожие вопросы: