2009-06-08 12 views
12

Recientemente me encontré con un código que parecía:¿Por qué llamar al operador sizeof con dos argumentos?

if(sizeof(var,2) == 4) { ... } 

(donde var es un tipo)

me quedé bastante sorprendido de ver lo que parecían ser dos argumentos para el operador sizeof. Un escaneo rápido del estándar ISO/ANSI C99 no produjo ningún secreto. No pude encontrar ninguna lectura de la gramática que permitiera una coma allí.

Al buscar en Google Code, pude encontrar an example de esta sintaxis en algún código PPC.

¿Es esto alguna sintaxis específica de PPC? Qué significa eso?

EDIT: Resulta que tanto lo que estaba viendo -, así como el código vinculada - es sintaxis específica a la WindRiver Diab compiler:

sizeof(type, int-const):

If int-const is 0 sizeof returns the size in bytes of type.

If int-const is 1 sizeof returns the alignment of type.

If int-const is 2 sizeof returns an integer constant designating the type of type. Look up "sizeof operator" in the Diab C/C++ User's Guide for values.

Wow, realmente han sobrecargado el significado del operador sizeof.

Edit2: documentación completa está aquí: http://www.vxdev.com/docs/vx55man/diab5.0ppc/c-additi.htm#3001432

+0

Es importante para esta discusión mencionar que "var" es un tipo. Porque eso descartaría al operador de coma. Pero "var" en su pregunta parece una variable. –

+0

Variable renombrada para mayor claridad. Gracias. –

+2

En Edit: Wow, eso es ... una complicación totalmente innecesaria del lenguaje C. C es lo suficientemente complicado ... Si quieres poder decir la alineación, escribe una alineación de función u operador, si insistes. Sheesh. (No es culpa tuya David, solo desahucio acerca de los malos implementadores del lenguaje ...) –

Respuesta

9

En investigaciones posteriores, descubrí que este es el comportamiento específico del WindRiver Diab compiler. Consulte EDIT en la pregunta para obtener más detalles.

+0

+1 para encontrar la respuesta correcta :) :) –

3

A mi me parece como una simple aplicación de la comma operator, que evalúa su primer argumento, tira a la basura el resultado, después evalúa su segundo argumento.

En este caso, se trata de determinar si el literal 2 tiene el tamaño 4. La parte "var" es irrelevante.

+0

Pensé lo mismo al principio, pero ¿cuál es el punto? Y si eso fuera cierto, entonces el código vinculado nunca funcionaría, ¿verdad? El segundo argumento es un int literal, por lo que su tamaño siempre será el tamaño de un entero en esa arquitectura. –

+0

Si se usaba el operador de coma, ¿no sería necesario encerrar el par en otro paréntesis? – veefu

+0

punto? ¿Por qué crees que tiene un punto? –

1

Parece una arenga roja. Supongo que estás usando accidentalmente el operador de coma y sizeof se está aplicando al último valor.

+0

Entonces, ¿por qué el código vinculado está escrito tal como está? Hmmm .... –

+1

¿Un nombre inapropiado? ¿Qué tiene el nombre equivocado? –

+1

@Rob, porque no soy un maestro de la lengua inglesa :). Lo cambié a un arenque rojo – JaredPar

0

Como se mencionó, el operador de coma se está aplicando y sizeof está devolviendo el tamaño de un entero de literal. A la inversa, esto parece un error por parte del autor, pero podría haber alguna codificación siniestra.

las expresiones sizeof no se evalúan, por lo que se pueden usar para varias cosas complicadas. Un ejemplo es proporcionar una referencia para una variable sin referencia, sin causar que el compilador genere ningún código. Vea this article sobre cómo crear una macro mejor para un ejemplo. Alexandrescu tiene algunos otros ejemplos de tamaño de engaño en Modern C++ Design, si la memoria sirve. Es posible, pero no probable, que uno de estos usos no obvios sea intencionado.

Cualquiera que sea el uso, si no se comenta en esta situación, es evidente que no vale la pena sacrificar la legibilidad y debe cambiarse.

0

Descargo de responsabilidad importante: El código siguiente es pseudocódigo. Los argumentos a sizeof nunca se evalúan en realidad, con el significado de "ejecutado", siempre es una compilación en tiempo de compilación (y por lo tanto una de las herramientas preferidas por los autores de plantillas, como las enumeraciones).

tenga en cuenta que tomé prestado auto a continuación desde C++ (0x); le dice al compilador para deducir el tipo de la expresión de inicialización y hace que los ejemplos un poco más simple

Lo que muchos no saben es que se puede invocar válidamente sizeof así:

auto s = sizeof int; 

es decir, sin paréntesis necesarios. Por lo tanto, si pasa (x, y) a sizeof, es equivalente a

auto c = (x,y); 
auto s = sizeof c; 

o simplemente

auto c = x,y; 
auto s = sizeof c; 

x,y es una secuencia, donde cada parte se evalúa de izquierda a derecha, y la secuencia obtiene el valor de la última parte, en este caso es y. Por lo tanto, el código original es más o menos equivalente a

auto s = sizeof y; 

Así que parece a mí que el compilador en cuestión hace algo muy, muy braindead, en el que se introduce una extensión que recopila también en otros compiladores, pero con una forma totalmente significado diferente. Esto es malo.

+0

Afortunadamente, gcc y MSVC no permiten esto. Código como 'sizeof (int, 2)' produce un error en ambos compiladores similar a: "' error: expected ')' before ',' token' ". –

+0

Me doy cuenta de que mi anser es incompleto. "int" en sí mismo no es una expresión evaluable; si escribe 'sizeof (5,5)' se compilará. –

Cuestiones relacionadas