Есть ли несогласованность на языке программирования C?

Где-то я читал, что профессор утверждал, что существует некоторая несогласованность в программировании программирования. Это правильно, и если да, то что это?

Я считаю, что я помню, что аргумент, который выдвинул профессор, заключался в том, что вы могли бы что-то сделать с одним типом (может быть, char), но не с другим (возможно, int), и что для согласованности должно быть возможно сделать то, что вы на самом деле можете t с C.

Вы знаете, что я имею в виду здесь, или нет поддержки этому понятию?

Related: https://stackoverflow.com/questions/3486059/inconsistency-in-programming-languages

2
Этот тип проектного вопроса, скорее всего, потребует обсуждения и не подходит для форматов technical Q & A StackOverflow. По существу, он, вероятно, будет закрыт. Тем не менее, это точно правильный предмет для Programmers.StackExchange.com - вы должны попросить его там.
добавлено автор Paul Turner, источник
Некоторые несоответствия упоминаются с точки зрения ортогональности здесь .
добавлено автор Reinier Torenbeek, источник

5 ответы

Есть несколько:

  • unlike other types, you can't assign or pass arrays directly as entire objects
  • char x[] declares either an array or a pointer, depending on where it occurs (in function parameters or not)
  • "str" behaves either as an array (in sizeof("str") or char s[] = "str") or as a pointer (in puts("str");)
  • "str" is of type char*, but you can't legally modify what it points to much like if it's const char*
  • you use %f for double in printf() but you use %lf for double and %f for float in scanf() and yet you use f for float constants (e.g. 1.0f)
  • -1 > 1u, not quite meaningful
  • UINT_MAX + 1 + 1.0 differs by a lot from UINT_MAX + 1.0 + 1, may be quite surprising as well
  • etc

Однако есть обходные пути почти везде.

3
добавлено

Он может быть фактом, что char может быть подписан или неподписанным по умолчанию, тогда как int всегда подписывается.

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

It may also be that sub-character types (ie, bitfields) are not addressable with the & address-of operator whereas other types like char, int and user-defined structures are. That's because multiple bitfields may be combined at a single address.

Я не сомневаюсь, что вы могли найти пятьдесят других незначительных несоответствий в C, ни одна из которых действительно не была бы причиной для того, чтобы вырвать язык.

1
добавлено
Спасибо за ответ. Я не требую полной согласованности. Я просто хотел узнать больше о C.
добавлено автор Niklas Rosencrantz, источник
"...is some inconsistency..."

Нет, это неверно, есть многочисленные несоответствия, множественное число. Для обозначения всех таких вопросов потребуется эссе многих страниц. Подводя итог: самое худшее, что вы можете сделать, - предположить, что язык C является здравым, последовательным или логичным.

Что касается конкретной проблемы с char, в C есть правило, гарантирующее, что все целые типы неявно подписаны. Например, запись int всегда полностью эквивалентна записи signed int . Это верно для int, long, short, long long , но не для char .

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

Причиной этого является, если я правильно помню, какая-то старая проблема обратной совместимости, когда компиляторы C, сделанные до первой стандартизации C, реализовали char по-разному.

Другая проблема с char и другими «малыми целыми типами» (short and bool) заключается в том, что всякий раз, когда они являются частью выражения, они неявно вводятся типами таким образом, который не согласуется с тем, как продвигаются более крупные целочисленные типы. Это известно как целые правила продвижения и являются частью «обычных арифметических преобразований» (

Может быть, это, что char не разрешено заполнять биты, а int : диапазон значений unsigned char всегда 2 CHAR_BIT широкий, в то время как знак signed char может быть до одного меньше - диапазон для типов int может 't определяется по его размеру и значению CHAR_BIT (если только CHAR_BIT равно 8 и sizeof (int) 2).

1
добавлено
char str[] = "Hello";
const char *str2 = "World";

If I understand you correctly, the above are 2 features that work meaningfully only for char

0
добавлено
Случай указателя отлично работает с любым типом указателя. const banana_t * str2 = "World"; должен компилироваться (но, надеюсь, давать предупреждения), и это нормально, если это не приведет к несогласованному результату; в этом случае это неопределенное поведение.
добавлено автор Lundin, источник
Строго говоря, случай banana_t может быть действительным, если он представляет собой структуру, содержащую n количество символов, и нет проблем с выравниванием. Но тогда, конечно, было бы лучше написать banana_t * b = {{'W', 'o'}, {'r', 'l'}, {'d', '\ 0'} };
добавлено автор Lundin, источник
@cdarke Я не имею в виду между ними, я имею в виду, что каждый оператор не имеет эквивалентной формы int (без незначительных изменений)
добавлено автор Karthik T, источник
@Lundin справедливо сказать тогда, что утверждение полезно только в этой форме? Разумеется, мы не можем определить массив int или массив banana_t в этой форме.
добавлено автор Karthik T, источник
Как это непоследовательность? Эти заявления совершенно разные.
добавлено автор cdarke, источник