Как сделать переносную 64-битную арифметику без предупреждений компилятора - PullRequest
17 голосов
/ 25 октября 2010

Иногда я использую 64-битную арифметику в моей библиотеке C ++ с открытым исходным кодом. Я обнаружил, что long long служит моей цели довольно хорошо. Даже какой-нибудь 10-летний солярис может его скомпилировать. И это работает без возни с #defines в Windows.

Теперь проблема в том, что я получаю жалобы от моих пользователей, потому что они компилируются с GCC -педанскими настройками, и GCC настаивает на выдаче предупреждений о том, что long long не является частью стандарта C ++. Это, вероятно, правильно, но я не слишком заинтересован в стандарте C ++ как таковом, я просто хочу, чтобы мой код работал на максимально возможном количестве компиляторов.

Итак, мой вопрос двоякий:

  • Кто-нибудь может назвать фактические компиляторы C ++, которые не поддерживают длинную 64-битную?
  • Есть ли способ заставить GCC компилировать 64-битную арифметику (на 32-битной платформе) без предупреждений компилятора? (stdint.h не помогает, так как также зависит от long long)

P.S.

Если есть платформы, на которых long long становится 128 бит или больше, это интересно, но не проблема для меня.

Ответы [ 7 ]

16 голосов
/ 25 октября 2010

Когда ваша библиотека предоставляется в качестве источника, одним из вариантов является предоставление «портирующего» заголовка, в котором ваши пользователи несут ответственность за предоставление 64-битного типа (вы должны указать имя).Тогда, естественно, они также обязаны иметь дело с любыми предупреждениями компилятора о том, что их выбор типа провоцирует, либо избегает их, либо подавляет их, либо игнорирует их.

Я думаю, это то, что вы называете "возиться с #defines", но я не думаю, что с этим слишком много проблем.Вы можете предоставить версию по умолчанию, которая будет просто использовать long long напрямую и будет работать на вашем 10-летнем ящике Solaris, а также на Windows, так что большинству пользователей никогда не придется приближаться к настраиваемой пользователем части вашей библиотеки.

Затем для педантичных пользователей вы можете предоставить версию для GCC, которая включает <sys/types.h> и использует int64_t вместо long long.Это не вызывает у меня никакого предупреждения с g++ -pedantic.Вы могли бы даже сделать это в версии по умолчанию, распознав GCC, который, безусловно, работает с #defines, но опять же не совсем так, как это обычно бывает в мультиплатформенном продукте.

Если ваша библиотека такжеЕсли для определенных платформ предусмотрены бинарные файлы, то, конечно, вы должны решить, какой будет 64-битный тип.Если он также появляется в интерфейсе библиотеки (и, следовательно, в заголовочном файле), вам просто нужно выбрать тот, который не будет вызывать никаких предупреждений с разумными опциями компилятора.Я думаю, что -pedantic - это разумный вариант компилятора, как, впрочем, и ваши пользователи, так что опять же это int64_t в GCC.

13 голосов
/ 25 октября 2010

В GCC используйте опцию компилятора -Wno-long-long для подавления этого конкретного предупреждения.

Вы также можете использовать -std=C++0x, но, вероятно, еще больше уменьшит переносимость.

5 голосов
/ 26 октября 2010

Вы также можете отключить предупреждение, используя функцию gcc "__extension__", например:

// No '-pedantic' warning/error.
__extension__ long long foo = 2;

// Exhibits '-pedantic' warning/error.
long long bar = 3

и компиляцию:

$ g++ -pedantic -fsyntax-only foo.cpp
foo.cpp:5: error: ISO C++ 1998 does not support 'long long'

Обратите внимание, чтотолько последнее использование long long вызвало ошибку -pedantic, поскольку не было добавлено ни __extension__.В любом случае, я бы согласился с @ предложением Стива Джессопа об использовании int64_t.

5 голосов
/ 25 октября 2010

Если вы не можете управлять переключателями, передаваемыми в gcc, вы можете отключить предупреждение с помощью #pragma.

http://gcc.gnu.org/onlinedocs/gcc/Diagnostic-Pragmas.html

4 голосов
/ 25 октября 2010

Вы можете отключить предупреждение с помощью -Wno-long-long (убедитесь, что оно приходит после -pedantic).C99 требует 64-битных целых чисел, и я думаю также C ++ 0x, поэтому компиляторы, у которых их нет, в наши дни становятся редкостью.

1 голос
/ 26 октября 2010

Если у вас есть Boost в системном каталоге включения, вы можете сказать:

#include "boost/cstdint.hpp"
boost::int64_t my_64_bit_number;

Если он находится в системном каталоге включения, предупреждения автоматически подавляются.

0 голосов
/ 25 октября 2010

Вы можете заменить использование long long одной из множества библиотек C ++ bigint.Я уверен, что некоторые из них избегают этой ошибки компилятора.Лично я предпочел бы придерживаться ошибки.

...