¿Cuál es el propósito del operador unario más (+) en C?

8 minutos de lectura

avatar de usuario
zneak

En C, es legal escribir algo como:

int foo = +4;

Sin embargo, por lo que sé, la suma unaria (+) en +4 es un no-op. ¿Lo es?

  • No exactamente lo mismo, pero relacionado: stackoverflow.com/questions/727516/…

    – jglouie

    9 de julio de 2011 a las 19:33


  • msdn.microsoft.com/en-us/library/s50et82s.aspx “El operador unario más que precede a una expresión entre paréntesis fuerza la agrupación de las operaciones encerradas. Se utiliza con expresiones que involucran más de un operador binario asociativo o conmutativo. El operando debe tener tipo aritmético. El resultado es el valor del operando. Un operando integral experimenta promoción integral. El tipo del resultado es el tipo del operando promovido”.

    – Tim S.

    9 de julio de 2011 a las 19:36

  • K&R dice que solo se agregó por simetría en el estándar.

    – Aarón Yodaiken

    10 de julio de 2011 a las 2:44

  • @Jeremy: hay. por ejemplo dice que +short(1) tiene tipo intno short.

    – MSalters

    11 de julio de 2011 a las 10:19

  • @TimS.: “El operador unario más que precede a una expresión entre paréntesis fuerza la agrupación de las operaciones encerradas“- ¿Ah? Son los paréntesis, no el +que fuerza la agrupación.

    –Keith Thompson

    30 de junio de 2013 a las 22:24

Puede usarlo como una especie de afirmación de que una expresión tiene tipo aritmético:

#define CHECK_ARITHMETIC(x) (+(x))

Esto generará un error en tiempo de compilación si x evalúa a (digamos) un puntero.

Ese es el único uso práctico que se me ocurre.

  • También puede convertir un valor de enumeración en su valor entero de esta manera.

    – GManNickG

    9 de julio de 2011 a las 21:14

  • ¿Por qué no puedes hacer lo mismo con, por ejemplo, (-(-(x)))?

    – Aarón Yodaiken

    10 de julio de 2011 a las 1:06

  • @luxun @zneak: Interesante idea… Déjame ver… OK, ¿qué tal esto? Si int es de 32 bits y x pasa a ser un int igual a -2^31luego -x desbordará un entero con signo que técnicamente es un comportamiento indefinido. 🙂

    – Nemo

    10 de julio de 2011 a las 3:40


  • @zneak: el punto es desencadenar un error de tiempo de compilación si la expresión tiene un tipo de puntero, pero no operar si tiene un tipo aritmético. Su versión funciona bien, excepto por las expresiones aritméticas que se evalúan como INT_MIN. (Bueno, en teoría, de todos modos. En la práctica, probablemente funcione bien en cualquier máquina realista). Aún así, una lectura estricta del estándar dice que estos son diferentes.

    – Nemo

    10 de julio de 2011 a las 5:34

  • @zneak: incluso si no lo usa en una tarea, simplemente para evaluar -x Cuándo x es INT_MIN es técnicamente para invocar un comportamiento indefinido, creo.

    – Nemo

    10 de julio de 2011 a las 6:31

Según el estándar C90 en 6.3.3.3:

El resultado del operador unario + es el valor de su operando. La promoción integral se realiza sobre el operando. y el resultado tiene el tipo promocionado.

y

El operando del operador unario + o – tendrá tipo aritmético..

  • Entonces +x es un noop a menos sizeof x < sizeof(int)?

    – zneak

    9 de julio de 2011 a las 19:45

  • Estas citas del estándar muestran que el + unario no es simplemente un no-op. Realiza una promoción integral en el operando. Y, posiblemente más importante, convierte un valor l en un valor r.

    – Sander de Dycker

    9 de julio de 2011 a las 19:48

  • Bueno, es teóricamente posible que sizeof(short) == sizeof(int) pero un short tiene relleno y, en teoría, en un sistema de este tipo, es posible que sea necesario poner a cero el relleno o extender el signo. Teóricamente.

    -Dietrich Epp

    9 de julio de 2011 a las 19:49

  • Tenga en cuenta que cuando dice tipo aritmético se refiere tanto a tipos integrales como a tipos flotantes, el ejemplo que muestra Nemo funciona porque los punteros están fuera de esta clasificación. Los tipos integrales y los punteros forman tipos escalares.

    – lccarrasco

    9 de julio de 2011 a las 19:55


  • Esto no afecta a un float o un double en absoluto, ¿verdad?

    – SS Ana

    13 de enero de 2020 a las 22:28

Hay un uso muy útil del operador unario más que conozco: en macros. Supongamos que quieres hacer algo como

#if FOO > 0

Si FOO no está definido, el lenguaje C requiere que sea reemplazado por 0 en este caso. Pero si FOO se definió con una definición vacía, la directiva anterior dará como resultado un error. En su lugar, puede utilizar:

#if FOO+0 > 0

Y ahora, la directiva será sintácticamente correcta si FOO no está definido, está definido en blanco o está definido como un valor entero.

Por supuesto, si esto producirá la semántica deseada es una cuestión completamente distinta, pero en algunos casos útiles lo hará.

Editar: Tenga en cuenta que incluso puede usar esto para distinguir los casos de FOO siendo definido como cero versus definido como en blanco, como en:

#if 2*FOO+1 == 1
/* FOO is 0 */
#else
/* FOO is blank */
#endif

  • ¿Está seguro de que estas directivas de preprocesador realmente se relacionan con el operador unario + como se ve en C? En tu segundo ejemplo, con un espacio en blanco FOOla expresión no sería válida C.

    – zneak

    9 de julio de 2011 a las 23:45

  • De hecho lo hace. En cualquier caso, el par de operadores - - (¡espacio esencial!) es equivalente a + por lo que puedo decir, haciendo + bastante redundante… No, eso está mal, no es equivalente cuando el operando es INT_MIN… 🙂

    – R.. GitHub DEJA DE AYUDAR A ICE

    10 de julio de 2011 a las 2:49


  • Perdón por rechazar una respuesta tan antigua, pero ¿no es este un ejemplo del plus binario en lugar del plus unario?

    – Aurora Vollvik

    2 de noviembre de 2018 a las 15:54

  • @AuroraVollvik: Es una ventaja si la macro está definida pero con una definición vacía.

    – R.. GitHub DEJA DE AYUDAR A ICE

    2 de noviembre de 2018 a las 16:15

  • @UndefinedBehavior: si es unario o binario depende de cómo FOO se define.

    – R.. GitHub DEJA DE AYUDAR A ICE

    7 de febrero de 2019 a las 19:02

bastante Está presente principalmente para completar, y para hacer que construcciones como esta se vean un poco más limpias:

int arr[] = {
    +4,
    -1,
    +1,
    -4,
};

avatar de usuario
como bhullar

Encontré dos cosas que unarias + operador hacer es

  • integer promotion
  • turning lvalue into rvalue

ejemplo de promoción de enteros:

#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;
}

Salida típica (en plataforma de 64 bits):

1 2 4 8
4 4 4 8

convertir lvalue en rvalue ejemplo:

int i=0,j;

j=(+i)++; // error lvalue required

  • Finalmente. Una aplicación potencialmente útil que informará a algún código genérico del tamaño de un argumento después de la promoción de enteros que puede no ser sizeof(int). No tengo idea de cuándo lo usaré. Pero agradable de todos modos. NB: respuesta editada para mostrar que no todo va a 4.

    – perseverancia

    7 de septiembre de 2017 a las 11:08

avatar de usuario
delan azabani

No es precisamente un no-op

el unario + El operador solo hace una cosa: aplica las promociones enteras. Dado que ocurrirían de todos modos si el operando se usara en una expresión, uno imagina que unario + está en C simplemente por simetría con unario -.

Es difícil ver esto en acción porque las promociones generalmente se aplican.

Se me ocurrió esto:

printf("%zd\n", sizeof( (char) 'x'));
printf("%zd\n", sizeof(+(char) 'x'));

que (en mi Mac) imprime

1
4

  • Finalmente. Una aplicación potencialmente útil que informará a algún código genérico del tamaño de un argumento después de la promoción de enteros que puede no ser sizeof(int). No tengo idea de cuándo lo usaré. Pero agradable de todos modos. NB: respuesta editada para mostrar que no todo va a 4.

    – perseverancia

    7 de septiembre de 2017 a las 11:08

avatar de usuario
Comunidad

¿Cuál es el propósito del operador unario ‘+’ en C?

Unario más se agregó a C para la simetría con unario menos, de la Justificación de la Norma Internacional—Lenguajes de Programación—C:

Unary plus fue adoptado por el Comité C89 a partir de varias implementaciones, por simetría con unary minus.

y no es un no-op, realiza las promociones enteras en su operando. Citando mi respuesta a ¿El operador Unary + escribe conversiones?:

El borrador de la sección estándar C99 6.5.3.3 Operadores aritméticos unarios dice:

El resultado del operador unario + es el valor de su operando (promocionado). Las promociones enteras se realizan en el operandoy el resultado tiene el tipo promocionado.

Vale la pena señalar que Manual de referencia de C++ anotado(BRAZO) proporciona el siguiente comentario sobre unary plus:

Unary plus es un accidente histórico y generalmente inútil.

  • En C++ también se “abusa” cuando un static_cast mostraría la intención más claramente, por ejemplo, Resolver una sobrecarga ambigua en el puntero de función y std::function para una lambda usando +

    – Shafik Yaghmour

    30 de noviembre de 2017 a las 16:46

¿Ha sido útil esta solución?

Esta web utiliza cookies propias y de terceros para su correcto funcionamiento y para fines analíticos y para mostrarte publicidad relacionada con sus preferencias en base a un perfil elaborado a partir de tus hábitos de navegación. Al hacer clic en el botón Aceptar, acepta el uso de estas tecnologías y el procesamiento de tus datos para estos propósitos. Configurar y más información
Privacidad