У C законно писати щось на зразок:
int foo = +4;
Однак, наскільки я можу зрозуміти, одинарний плюс ( +
) у +4
- це ні. Є це?
У C законно писати щось на зразок:
int foo = +4;
Однак, наскільки я можу зрозуміти, одинарний плюс ( +
) у +4
- це ні. Є це?
+short(1)
має тип int
, а не short
.
+
, що змушує групувати.
Відповіді:
Відповідно до стандарту C90 у 6.3.3.3:
Результатом оператора unary + є значення його операнда . Цілісне просування виконується на операнді. і результат має підвищений тип.
і
Операнд унарного оператора + або - повинен мати арифметичний тип .
+x
це петля хіба що sizeof x < sizeof(int)
?
sizeof(short) == sizeof(int)
але a short
має заповнення, і теоретично в такій системі відступ може знадобитися обнулити або розширити знак. Теоретично.
float
чи a double
, правда?
Ви можете використовувати це як своєрідне твердження, що вираз має арифметичний тип:
#define CHECK_ARITHMETIC(x) (+(x))
Це генерує помилку під час компіляції, якщо x
обчислюється (скажімо) вказівником.
Це приблизно єдине практичне використання, яке я можу придумати.
(-(-(x)))
?
int
є 32-розрядним і, як x
виявляється, int
дорівнює -2^31
, то -x
переповнює підписане ціле число, яке є технічно невизначеною поведінкою. :-)
INT_MIN
. (Ну, теоретично, так чи інакше. На практиці це, мабуть, чудово працює на будь-якій реалістичній машині.) Однак, суворе читання стандарту говорить про те, що вони різні.
-x
коли x
це INT_MIN
технічно викликати невизначений поведінка, я вважаю.
Я знаю одне дуже зручне використання оператора unary plus в макросах. Припустимо, ви хочете зробити щось подібне
#if FOO > 0
Якщо FOO
не визначено, мова C вимагає, щоб у цьому випадку його замінили на 0. Але якщо це FOO
було визначено з порожнім визначенням, вищевказана директива призведе до помилки. Натомість ви можете використовувати:
#if FOO+0 > 0
І тепер директива буде синтаксично правильною, незалежно від того FOO
, визначена вона, визначена як порожня або визначена як ціле число.
Звичайно, чи це дасть бажану семантику - це зовсім окреме питання, але в деяких корисних випадках це буде.
Редагувати: Зверніть увагу, що ви навіть можете використовувати це, щоб розрізнити випадки, коли FOO
вони визначаються як нуль, ніж визначені як порожні, як у:
#if 2*FOO+1 == 1
/* FOO is 0 */
#else
/* FOO is blank */
#endif
FOO
, вираз не буде дійсним C.
- -
(просторових!) Еквівалентна +
, наскільки я можу зрозуміти, зробити +
досить зайвою ... Ні, це неправильно, це не рівнозначно, коли операндом є INT_MIN
... :-)
FOO
це визначено.
Доволі багато. Це головним чином для повноти, і щоб зробити подібні конструкції виглядають трохи чистішими:
int arr[] = {
+4,
-1,
+1,
-4,
};
+
s.
Унарний +
оператор робить лише одне: застосовує цілочисельні підвищення . Оскільки вони все одно мали б місце, якби операнд був використаний у виразі, уявляємо, що одинарний +
є в C просто для симетрії з одинарним -
.
Важко побачити це в дії, оскільки рекламні акції застосовуються настільки загалом.
Я придумав таке:
printf("%zd\n", sizeof( (char) 'x'));
printf("%zd\n", sizeof(+(char) 'x'));
який (на моєму Mac) друкує
1
4
char
s на C ++ за допомогою std::cout
.
Яке призначення одинарного оператора '+' в C?
Одинарний плюс було додано до C для симетрії з одинарним мінусом із Обґрунтування міжнародного стандарту —Мови програмування — C :
Одинарний плюс був прийнятий Комітетом C89 з декількох реалізацій, для симетрії з одинарним мінусом.
і це не операція, вона виконує цілочисельні акції на своєму операнді. Посилання з моєї відповіді на запитання Чи оператор Unary + робить перетворення типів?:
У проекті стандартного розділу C99 6.5.3.3
Унарні арифметичні оператори сказано:
Результатом унарного + оператора є значення його (розкрученого) операнда. Цілі числа підвищуються на операнді , а результат має підвищений тип.
Варто зазначити, що Анотований довідковий посібник C ++ ( ARM ) містить наступний коментар до унарних плюсів:
Одинарний плюс - це історичний випадок і взагалі марний.
static_cast
чіткіше показує намір, наприклад Вирішення неоднозначного перевантаження покажчика функції та функції std :: для лямбда за допомогою +
Я знайшов дві речі, які робить одинарний +
оператор
integer promotion
turning lvalue into rvalue
Приклад цілочисельного просування:
#include <stdio.h>
int main(void) {
char ch;
short sh;
int i;
long l;
printf("%d %d %d %d\n",sizeof(ch),sizeof(sh),sizeof(i),sizeof(l));
printf("%d %d %d %d\n",sizeof(+ch),sizeof(+sh),sizeof(+i),sizeof(+l));
return 0;
}
Типовий вихід (на 64-бітній платформі):
1 2 4 8
4 4 4 8
перетворення lvalue у приклад rvalue:
int i=0,j;
j=(+i)++; // error lvalue required
sizeof(int)
. Я навіть не уявляю, коли буду цим користуватися. Але приємно все одно. NB: відредагована відповідь, щоб показати, що не все йде до 4.
Під "ні-op" ви маєте на увазі інструкцію по збірці?
Якщо так, то точно ні.
+4 - це просто 4 - компілятор не додаватиме подальших інструкцій.
+(char)4
це не те саме, що (char)4
.