Pull to refresh

Comments 73

Ну тут как бы сама преамбула немного намекает на тему, что это типичный случай когда "рад бы в рай, да грехи не пускают". Windows — сильно особая платформа. Там больше 10 лет ушло на то, чтобы этот простейший заголовочный файл создать. Но да, не то в 2010й, не то в 2012й версии он наконец-то появился. Уря! Костыли можно потихоньку выкидывать...
<сарказм>А что же делать с VC 6, она же наверное эти вообще шаблоны не скомпилирует</сарказм>
<прикинувшись ветошью>Почему это не скомпилирует? Скомпилирует, скорее всего. Сейчас под рукой VC 6 нету, но я не вижу тут ничего, что могло бы помешать этому на VC 6 собраться. Там проблемы с частичной специализацией были, но тут её вроде как нету...</прикинувшись ветошью>
На самом деле я сталкивался с проектами, собиравшимися VC 6 ещё не так давно. Вы думаете статьи подобные этой на ровном месте возникают?
Я думаю и даже знаю, что до сих пор есть современные проекты, которые пишут на ASP (не ASP.Net) и PHP4. Но надо ж как-то из анабиоза выходить.
Может и не скомпилить. Qt компилит, только если вынести внутренние шаблоны из класса. Сам класс я написал в 2011-м году и честно говоря тогда даже не знал о stdint.h
по факту, stdint.h появился в том же самом 11-м стандарте, в котором появились type_traits (всякие std::is_signed и подобное), которые ты использовал в своем хедере
stdint.h появился в стандарте С99. Это cstdint появился в 11-м стандарте =)
А разве в сети не найти файл stdint.h? когда у иная возникла проблема его отсутствия, я его выбрал из mingw и всё.
Хотя в качестве концепта такая магия может и интересна где нибудь на bare metal железе. Но даже для них можно взять newlib.
Это инженерный подход, так не интересно! sarcasm mode off
А разве в сети не найти файл stdint.h? когда у иная возникла проблема его отсутствия, я его выбрал из mingw и всё.
Хотя в качестве концепта такая магия может и интересна где нибудь на bare metal железе. Но даже для них можно взять newlib.
Да почему же, он всем хорош. Наверное это и вправду велосипед, но я привык уже его использовать
Хотите — используйте. Но хотя бы замените в нём char на signed char, если хотите переносимости!
Вы правы, если уж я сослался на ISO, то нужно и long long заменить на long long int, хотя честно я не работал в системах где нет таких синонимов.
Дело не в синонимах. Дело в том, что тип данных char может быть как знаковым, так и нет, в зависимости от настроек компилятора.
Именно. А "long long" — это как раз стандарт. "Неявный int" можно опускать...
При чём тут 3.9.1? Там типы перечислены. Как их можно в программе называть — в 7.1.6.2 написано.
Типы из cstdint меня устраивают полностью, я написал класс вычисляемого размера в 2011-м и тогда даже не знал о cstdint.
UFO just landed and posted this here
Вам не надоело тролить в каждом посте по C++? Или этоту вас весеннее?
UFO just landed and posted this here
На самом деле, кто хотел на VS иметь stdint.h, тот имел благодаря проекту msinttypes.
Вообще-то в VS и так есть этот хедер, сколько себя помню. С VS2012 точно.
stdint.h появился в VisualStudio начиная с десятой версии (которая VS 2010). В девятой версии (VS2008) ее нет.
А насчёт "десятки стандартных типов" — это такая шутка? Вообще-то стандартных типов не 10, а 11. Про "signed char" вы забыли. Тот факт что по-умолчанию char может быть не только теоретически, но и практически любым выпило много крови тем, кто переносит код с x86 (где на большинстве компиляторов он знаковый) на ARM (где по умолчанию он беззнаковый).
Я уже отписался выше, это не шутка, это ошибка. Конечно signed char как и long long int. Конечно о 10-ке (как и о 11-и) говорить не корректно, лучше просто сослаться на параграф 3.9.1., пункты 2 и 3 http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2011/n3242.pdf
Только сейчас прочитав статью заметил "небесспорный приём". Во-первый — он таки "бесспорный" (см. SFINAE). Во-вторых — ненужный.
В большинстве случаев будет достаточным сделать так:
template <int x> struct unsupported_capacity;
template <> struct unsupported_capacity<1> {};
template <> struct unsupported_capacity<2> {};
template <> struct unsupported_capacity<4> {};
template <> struct unsupported_capacity<8> {};

Это, правда, даст возможность описывать указатели на, скажем, "struct unsupported_capacity<3>" — но практически этого достаточно: где-то же в программе вы этот указатель захотите-таки разименовать? Вот там и получите ошибку...
Мне кажется, под спорностью автор имел вообще использование такого вспомогательного класса, а не то, что он имеет тело с массивом неизвестного размера.
Кстати, размер проще было просто делать отрицательным:
int i[8-x];
Спорность в том, что результат не гарантирован, а подыгран. Я не нашёл, чтобы стандарт предписывал в какой форме IDE должен сообщать об ошибках инстанцирования
Интегральными бывают суммы, схемы и теоремы Коши. А типы — целочисленные.
Вы мне напомнили моего преподавателя по алгебре в универе. Он говорил «числа бывают комплекснЫми. кОмплексные только обеды» )))
Первый раз вижу такое произношение, с ударением на "Ы" :) Обычно холивар идет между "О" и "Е"...
да, так и есть, я ошибся, быстро писал
Хочу немного позанудствовать. Вам никто не обещал что char будет иметь размер в один октет. Иными словами, тот факт что sizeof(char) == 1 не значит что char занимает ровно 8 бит. Он может быть размером 32 бита.
Вряд ли ваш код попадет на платформу где такое имеет бысто быть. Но если вдруг попадет — он там попросту сломается.
Поэтому, он не совсем кроссплатформенный.
Стандарт, кстати, гарантирует только сущесвование типов а-ля int_leastХХ_t и говорит что могут существовать системы где intXX_t просто не определен.
UFO just landed and posted this here
1 байт != 8 бит, как ни странно. 1 байт — минимальная адресуемая единица памяти.
UFO just landed and posted this here
"Парень" прав. 1 байт не всегда == 1 октет. На x86 они равны, но есть архитектуры, где 1 байт = 4 октета.
UFO just landed and posted this here
Тогда извиняюсь, был неправ. Но оператор sizeof всё-таки возвращает размер в байтах, а не в октетах.
По моему вы спорите "мимо" друг друга. Есть стандарт ANSI/ISO C (на самом деле теоретически это разные стандарты). Есть стандарт POSIX (который, кстати, Windows и не поддерживает сегодня — но поддерживала много лет назад).
В ANSI/ISO C размер байта не фиксирован. Может быть 8 бит, может быть 9, а может и все 36. Как карта ляжет. В POSIX — размер байта фиксирован. 8 бит без вариантов. Хотите ли вы поддерживать не-POSIX — системы (+Windows: из-за "наследственности там много чего реализовано "как в POSIX"), или весь спектр ANSI/ISO C систем? Это уж вам решать...
UFO just landed and posted this here
Не очень понятно с какого перепугу вы завели разговор про POSIX при том что он, в общем-то, начался с не-POSIX-совместимой платформы!
sizeof(char)==1 везде, на любой системе где есть компилятор C или C++.
Другое дело, что только POSIX гарантирует что длина байта равно 8 бит. ANSI C этого не обещает.
Гениально. Автор, ты изобрёл линейный поиск.
using integral_types = type_list<...>;
using uint8_t = find_if_t<integral_types, is_unsigned && has_8_bits>;
...
// Образно выражаясь.
Потерян ещё один тип: «signed char».
Действительно «signed int» идентичен типу «int».
А вот: «unsigned char», «signed char» и «char», это три разных типа.
Ну и кроме того не «интегральные», а «целочисленные». Интегральный это от слова integral, и связано это понятие с такой математической закорючкой. А целочисленный — это integer.
UFO just landed and posted this here
Логично называть целые числа со знаком "integer". И даже приемлимо всякое "int32" или "i32".
А вот например названия "uint32" или даже "u32", уже нелогичны. Особенно если незнать о происхождении.
Зато подходит иное название "натуральное число". Как вам: "natural32", "natural64"?
Я для своих домашних проектиков давно создал хидер с псевдонимами:
typedef signed int32 integer32;
typedef unsigned
int32 natural32;
Мне так больше нравится. Более логичные названия.
Срочно читать Фейнмана. Про "улучшенную тригонометрию". uint32_t может выглядеть безумием — но это стандарт. Любой, кто использует C/C++ должен про него знать. Хотя на практике, конечно, есть люди знающие C/C++ на уровне Эллочки-людоедки, но им ваши обозначения тоже не помогут.
В программировании и без вас достаточно сложностей и непонятностей — незачем изобретать новые. С одной стороны ваши "домашние проектики" — они лично ваши и вы можете делать что хотите. С другой — а вдруг по работе пригодится? Всё переписывать только из-за того, что вам uint32_t не нравится?
Более логичные с точки зрения кого? Signed/unsigned — стандарт. В процессоре (если говорить о x86) отдельно разведены команды signed и unsigned арифметики.
Дополню соседние комментарии — даже если предположить, что использование такого псевдонима оправдано, его имя не соответствует действительности.
Натуральные числа — это ряд чисел 1, 2, 3, …, представляющих собой число предметов или более строго — мощности (количества элементов) непустых конечных множеств.
Первая ссылка в гугле

unsigned же может иметь нулевое значение, ломая всю "абстракцию".
В зарубежной литературе натуральные числа обычно начинаются с 0
Кстати, в натуральном ряде нет нуля, если уж вы о чистоте наименований.
Таким образом ваш тип — это целые неотрицательные числа.
Поэтому стандартное обозначение лучше отражает истиное положение вещей чем ваше.
Спорно, является ли ноль натуральным числом. Некоторые допускают.
Но я вас понял. Всем спасибо за вразумление. Исправлюсь!
Тут не очем спорить. Это математическое понятие, которое строго определено и не допускает никаких неоднозначностей.
Да, похоже, я был не прав. У меня математическое образование и мы всегда оперировали примерно таким
определением
image отсюда:

натурального ряда. Определение Бурбаки как-то прошло мимо меня.
В английском языке, когда речь идет о типах данных, "integral" — это прилагательное, а "integer" — это существительное.
"integral" переводится как "целочисленный", а "integer" — как "целое число".
Значение "математическая закорючка" у слова "integral" тоже есть, но в этом значении это слово является уже существительным, а не прилагательным, поэтому никто не путается (кроме программистов по всему миру).
Так то в английском. Здесь же проблема неверного перевода. Как, например, с "органической едой". Или "софистицировать". Или "экспертиза". Толпы их.
Да, но перевод из того комментария, на который я отвечал, столь же неверный. Особенно в части
А целочисленный — это integer.
Даже на одной аппаратной платформе, например x86_64 (ia32e), разные ОС по разному интерпретируют резиновые целочисленные типы, введенные в С/C++ в качестве базовых. Резиновые они потому, что стандарт не определяет их длины, он только вводит отношения
sizeof(short int) \le sizeof(int) \le sizeof(long int) \le sizeof(long long int)
Это значит, что не исключается случай, когда все эти типы будут иметь одинаковую длину.
Разумеется, использовать эти типы можно лишь в том случае, если программа ничего не выводит и не выводит, потому что даже одна и та же программа, скомпилированная на разных платформах и/или разными компиляторами не сможет ввести данных, которые она вывела. Чтобы преодолеть это были введены жесткие типы, которые определены в stdint.h (). Эти типы локально настраиваются на соответсвующие резиновые в каждом конкретном случае установки компилятора на конкретную платформу, если таковые там присутствуют.
Как только возникает необходимость в бинарном выводе/вводе, эти типы должны использоваться безусловно. Они обладают абсолютной переносимостью, поскольку описываются в обязательной части стандарта.
Кстати, аналогичная ситуация может случиться при выводе/вводе символов — байт, вопреки расхожему мнению, это не 8 бит, а минимальная порция данных в адресуемой оперативной памяти. Так что запросто может случиться, что char может занимать, например, 12 бит.
В этой связи гораздо более полезно читать стандарт, чем толстые книги, переиздаваемые чуть ли не каждый год. Кстати, стандарт нужно читать не весь, а только до приложений, поскольку в приложения попадают ангажированные тексты спонсоров, пытающиеся возглавить то, что не удается разрушить.
Полностью поддерживаю. Только пожалуйста, не надо называть 11-й стандарт новым. Уже полтора более новых стандарта вышло.
У всех разное понятие о "новизне". Многие и Fortran 90 "новым" называют, хотя с тех пор аж три с половиной новых стандарта вышло...
Вы большой молодец и у вас много времени. Но зачем это нужно было-то? На дворе 2016 год.
Sign up to leave a comment.

Articles