LINUX.ORG.RU

char это и не signed и не unsigned а непонятно что

 


3

6
> cat main.cpp
#include <type_traits>

int main() {
        static_assert((::std::is_same<char, signed char>::value) == true);
        static_assert((::std::is_same<char, unsigned char>::value) == true);

        return 0;
}

> g++ -Wall -Wextra main.cpp
main.cpp: In function 'int main()':
main.cpp:4:2: error: static assertion failed
  static_assert((::std::is_same<char, signed char>::value) == true);
  ^~~~~~~~~~~~~
main.cpp:5:2: error: static assertion failed
  static_assert((::std::is_same<char, unsigned char>::value) == true);
  ^~~~~~~~~~~~~
★★★★

Все правильно.

C++17 Черновик стандарта n4659.

6.9.1
Fundamental types
[basic.fundamental]

Objects declared as characters (char) shall be large enough to store any member of the implementation’s basic character set. If a character from this set is stored in a character object, the integral value of that character object is equal to the value of the single character literal form of that character. It is implementation-defined whether a char object can hold negative values. Characters can be explicitly declared unsigned or signed. Plain char, signed char, and unsigned char are three distinct types, collectively called narrow character types...

Т.е. стандарт явно говорит, что это три разных типа.

rumgot ★★★★★
()
Последнее исправление: rumgot (всего исправлений: 2)
Ответ на: комментарий от untitl3d

Если бы там просто алиас, то следующий вывод был бы в двух случаях из трех одинаковый:

#include <iostream>

using namespace std;

int main() {
    cout << typeid(char).name() << endl;
    cout << typeid(unsigned char).name() << endl;
    cout << typeid(signed char).name() << endl;
}
c
h
a

И кроме того в случае алиаса один из двух static_assert из темы проходил бы.

rumgot ★★★★★
()
Последнее исправление: rumgot (всего исправлений: 3)
Ответ на: комментарий от Usruser

В С++ можно создавать свои типы.

И при добавлении в стандарт чёго-то, многое из этого делается на С++, а не магически добавляется в компилятор.

да, тип byte это: enum class byte : unsigned char {};

fsb4000 ★★★★★
()
Ответ на: комментарий от fsb4000

Честно говоря нужен ли этот std::byte? У меня есть сомнения. Нужен точно 8-битный тип, так есть же int8_t / uint8_t. Только что ограничение по операциям. Но хз, насколько это полезная фича.

rumgot ★★★★★
()
Последнее исправление: rumgot (всего исправлений: 2)
Ответ на: комментарий от rumgot

byte и int8_t это очень разные типы. Byte это байт, а не восьмибитный int. Т.е. арифметика к нему по умолчанию неприменима. Она не имеет смысла. Так же, как и нелепа арифметика с char, но тут уж исторически сложившееся безобразие.

Usruser
()
Ответ на: комментарий от Usruser

Т.е. арифметика к нему по умолчанию неприменима

Что я и так указал. Разница в виде некоторых ограничений.

А что касается размера - так он в большинстве систем будет одинаков.

rumgot ★★★★★
()
Ответ на: комментарий от rumgot

Разница в виде некоторых ограничений.

Да нет же. Это совсем разные типы. Ну как яблоки и сапоги. Byte, char и int8_t не имеют между собой абсолютно ничего общего кроме исторических корней.

Задача байта дёрнуть там N-ный бит нормальным, прямолинейным способом, а не с помощью наркоманских костылей. Может ещё какая битовая возня.

В общем тип, на мой взгляд, выглядит совершенно логичным и полезным.

Usruser
()
Ответ на: комментарий от Usruser

Задача байта дёрнуть там N-ный бит нормальным, прямолинейным способом, а не с помощью наркоманских костылей.

Ну покажи, как дернуть бит через std::byte и как через char / uint8_t.

rumgot ★★★★★
()
Ответ на: комментарий от rumgot

Сейчас byte ничего такого не умеет. Но должен уметь. Это его суть.

Что ты пытаешься сказать? Я утверждаю что

Byte, char и int8_t не имеют между собой абсолютно ничего общего кроме исторических корней.

У тебя есть возражения?

Usruser
()
Ответ на: комментарий от Usruser

Формально разные (но только без этих твоих очень/совсем).

Если бы мы представляли этими типами байты (ну с добавлением соответствующего типа в основании), то их использование одинаковое. И отличие от использования uint8_t для представления восьмибитных байт только в ограничениях, которые несут типы перечислений с областью видимости.

rumgot ★★★★★
()
Последнее исправление: rumgot (всего исправлений: 1)
Ответ на: комментарий от rumgot

Если бы мы представляли этими типами байты

Да, а сапоги и яблоки одинаково неуместны если бы мы запихивали их в жопу.

У нас очень разные подходы. Я сравниваю типы по их логической сути, а ты, кажется, по их реализации. Для меня это совсем дико и перечёркивает саму концепцию типов, превращая код в ассемблер или, прости Ктулху, в Питон какой-то.

Usruser
()
Ответ на: комментарий от Usruser

Я сравниваю типы по их логической сути, а ты, кажется, по их реализации. Для меня это совсем дико и перечёркивает саму концепцию типов

Покажи что-то на Haskell.

Oldboy
()
Ответ на: комментарий от Usruser

Не пиши эту аналогию с яблоками. Это идиотизм.

У нас очень разные подходы. Я сравниваю типы по их логической сути, а ты, кажется, по их реализации. Для меня это совсем дико и перечёркивает саму концепцию типов, превращая код в ассемблер или, прости Ктулху, в Питон какой-то.

Я сравниваю по разным признакам. Один из признаков - это то как их использовать.

Посмотри пример на cppreference. Там для вывода в поток сначала идет преобоазование в целочисленный, потом в bitset. И в чем в таком случае профит?

rumgot ★★★★★
()
Ответ на: комментарий от rumgot

Наркоманы.

Ещё на 32 битах int и long одинакового размера и абсолютно одинаково себя ведут но почему-то считаются разными и иногда компилятор ругаяется без каста. Ещё из-за этого возникат ситуация когда в параметр int32_t нельзя без каста передать int32 потому что один из них int, а другой long. На 64 битах и/или компиляторе Microsoft опять всё по другому.

Мне нравится подход у Оберона когда в документации прямо написано:

Appendix C: Domains of Basic Types

TypeDomain
BOOLEANFALSE, TRUE
SHORTCHAR0X .. 0FFX
CHAR0X .. 0FFFFX
BYTE-128 .. 127
SHORTINT-32768 .. 32767
INTEGER-2147483648 .. 2147483647
LONGINT-9223372036854775808 .. 9223372036854775807
SHORTREAL-3.4E38 .. 3.4E38, INF (32-bit IEEE format)
REAL-1.8E308 .. 1.8E308, INF (64-bit IEEE format)
SETset of 0 .. 31
X512 ★★★★★
()
Ответ на: комментарий от EXL

какую стройную систему? я видела архитектуры, где char 32 бита, потому что там так устроена работа с шиной и меньше 32 битов адресации нет.

всё зависит от железа и его возможностей. что подразумевают под char - непонятно, без уточнения архитектуры. это вон ламеры, которые кроме маздая на интеле ничего не видели, считают, что типы могут иметь фиксированную длину. но в реальности это не так. более того, и знаковость, и порядок битов, и ширина шины и прочие вещи также зависят от архитектуры. и чего-то может вообще не быть. а Си - универсальный инструмент, он работает под тысячами разных архитектур. в нём нельзя прибить гвоздями стандарт к какой-то конкретной реализации. плохо, если люди этого не понимают.

Iron_Bug ★★★★★
()
Ответ на: комментарий от EXL

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

Iron_Bug ★★★★★
()
Ответ на: комментарий от mxfm

Ты меня с кем-то перепутал? Я не утверждал, что типы одинаковые. Вообще, в си это железозависимо будет ли простой char signed или unsigned. Я думал что плюсы это недоразумение унаследовали, но тут говорят что нет.

untitl3d
()
Ответ на: комментарий от Iron_Bug

какую стройную систему?

Такую, где ядро языка имеет типы с чётко оговоренной размерностью в битах (ибо в байте может быть далеко не 8 бит), а все остальные общеупотребимые типы вроде char и int опираются на них, а не наоборот, как сейчас.

EXL ★★★★★
()
Последнее исправление: EXL (всего исправлений: 1)

Ребята, то ли я дурак, то ли лыжи не едут. Какой байт 8 бит! Байт - это минимальная единица операции к оперативной памяти. Может и 8 бит, может и 3.

VIT
()
Ответ на: комментарий от bga_

что значит «нужно»? зависит от платформы, для которой ты пишешь и твоих намерений. чаще всего это не критично. но предполагать, что какой-то тип имеет фиксированную длину или что у тебя будет тип, который имеет конкретную длину, если код должен работать на разных платформах, нельзя. могут оказаться сюрпризы.

Iron_Bug ★★★★★
()
Ответ на: комментарий от rumgot

понимаешь, это не вопрос «удобства». это вопрос стандарта. и если ты хочешь делать переносимый ЯП, то не надо в стандарт пихать вещи, которые заведомо могут не поддерживаться. это только ограничивает применение языка и ничего не решает. вот были в бусте эти потоки и пусть бы там оставались. кто хочет «удобства», взял бы оттуда. а в стандарт такое тащить нельзя. но и «удобства» тут никакого, тащемта. кроссплатформа - это вообще отдельная тема и там всё гораздо сложнее и в стандарт точно не укладывается. обычно проекты пишут под конкретную ОС, ну или под POSIX, например. поэтому я не вижу тут никаких неудобств. это какая-то высосанная из пальца проблема. проблему кроссплатформенности оно не решает, но рушит переносимость комиляторов и библиотек.

Iron_Bug ★★★★★
()
Ответ на: комментарий от EXL

а при чём тут биты? это тоже какая-то хрень, с которой работать неудобно. байт появился как единица чтения данных с шины. шина росла, появились слова и двойные слова. сейчас там 64 бита, 128 бит. потом будет больше, вероятно. компилятору неудобно работать с отдельными битами, потому что адресация зависит от шины и размера регистров. и все ассемблеры и бинарные коды операций привязаны к этим значениям. а биты - это просто отдельные регистровые сдвиги. они иногда удобны, но работать с битами на уровне системы - это изврат.

Iron_Bug ★★★★★
()
Последнее исправление: Iron_Bug (всего исправлений: 1)
Ответ на: комментарий от EXL

вообще, чтобы этих странных вопросов не возникало, учить программирование надо с ассемблера. причём попробовать хотя бы три-четыре архитектуры. чтобы уяснить, что нет никаких типов данных, а есть данные в памяти, адреса и регистры. и тогда всё в голове встаёт на свои места и всё становится понятно.

Iron_Bug ★★★★★
()