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 )

Вроде бы хотели ввести тип byte, а char окончательно должен был стать буквой, а не байтом. Но, вроде, что-то не доделали.

Usruser ()
Ответ на: комментарий от 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

Так же, как и нелепа арифметика с char

Ну здрасьте. Следующий/предыдущий символ в алфавите получить надо уметь.

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

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

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

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

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

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

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

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

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

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

То, что размер трёх видов char одинаковый не означает, что с точки зрения языка это одинаковые типы.

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

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

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

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

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

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

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

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

Usruser ()
Ответ на: комментарий от fluorite
struct logical_true {
    constexpr bool operator()(bool x) { return x; }
};
static_assert(logical_true()(std::is_same<char, signed char>::value));
fluorite ★★★★★ ()

Если бы C/C++ проектировали сегодня, то 100% добавили бы стройную систему типов, у которых явно прописана размерность и применение, а всю эту ахинею и беспорядок депрекейтнули.

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

Точно бы не получилась, Java совершенно для другого, она под JVM и там даже unsigned типов не положили.

Получился бы Rust, Zig или Hare.

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

Так в принципе Rust - это и есть C++ который проектировался сейчас.

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

А то что отличие только в ограничениях, как я и написал. А твои эти «очень разные» - это фантазерство.

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

Скажи, а вот

 enum class T1 {A, B, C, D};

и

 enum class T2 {A, B, C, D};

это «очень разные типы» или «отличие только в ограничениях»?

Мне кажется ты не в восторге от самой концепции типов.

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

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

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

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

О, индусского кода подвезли.

Ну хоть кто-то обратил внимание.

pr849 ()
Ответ на: комментарий от 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 ★★★★★ ()
Ответ на: комментарий от Iron_Bug

Считаешь ли ты что нужно использовать только [u]int_leastNN_t для хранения и [u]int_fastNN_t для вычислений и никакой фиксированной ширины типов?

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

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

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

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

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

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

Чёткости нет. Есть least, fast, хз какой int с unsigned братом и char для общения с ос

Ещё size_t с ssize_t.

Возможно ptrdiff если повезёт.

bga_ ★★★ ()

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

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

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

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

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

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

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

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

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

Iron_Bug ★★★★★ ()
Для того чтобы оставить комментарий войдите или зарегистрируйтесь.