2009-09-24 18 views
5

La apertura del código base Postgres, veo que gran parte del código C se escribe por tener punteros con el -> notación de tal manera que:C y el puntero notación

(foo)->next = 5; 

sé que la notación puntero tiene niveles de precedencia, tales que -> = (* foo). y no es lo mismo que * foo.

Sin embargo, ¿significa algo cuando los paréntesis están fuera del nombre de la variable y desreferenciando la dirección del próximo o es simplemente una convención que es endémica para un estilo de codificación?

Respuesta

6

Es una convención de codificación que no he visto antes.

Pero no cambia nada.

(foo)->next = 5; 

es exactamente equivalente a

foo->next = 5; 
+0

Impresionante, gracias. Eso es lo que pensé, y me pareció especialmente extraño ya que estaba en todas partes en la base de código. – mduvall

+1

Para ampliarlo, la razón por la que usarías esta construcción es como un cinturón de seguridad en caso de que foo sea una macro. Es la misma razón por la que algunas guías de estilo de C (por ejemplo, FreeBSD) sugieren que todas las declaraciones de devolución tienen el formato return (x); en lugar de simplemente devolver x; – Benno

+1

Aunque si 'foo' fuera una macro, sería aconsejable tenerlo entre paréntesis, p. '#define foo (blargity-> blah)' –

1

No tiene sentido. Los paréntesis no tienen ningún efecto ya que la expresión dentro de ellos es muy simple. Básicamente es

(*(foo)).next = 5; 

Que, como puede ver, es un conjunto extraño de paréntesis. Si así es como lo está haciendo el proyecto, adelante. De lo contrario, creo que se ve bastante horrible, así que trataría de no usarlo.

+0

Quizás quiso decir '' (* (foo)). next = 5; ''? –

+0

Oh. Derecha. Al menos ahora siento que hay una razón por la que no puedo concentrarme en mi tarea. Gracias por señalarlo, y gracias a Robert por arreglarlo. –

2

Es una convención de codificación para la seguridad.

En código simple, donde foo es solo un puntero, los parens son redundantes.

(foo)->next = 5; 

Sin embargo, tener en cuenta si hay o era la posibilidad de que fu podría ser definida por una macro por lo que es una expresión más compleja.

En ese caso, los parens pueden ser necesarios para evitar un error de compilación o, peor, para evitar una precedencia incorrecta. Imagínese si se traduce a una expresión feo como:

(++get_foo())->next = 5; 

o un molde común:

((db_record*)foo_ptr)->next = 5; 

algo a tener en cuenta con idiomática código C es que las macros se utilizan a menudo como un mecanismo de abstracción para cosas que podríamos hacer más explícitamente en otros idiomas ;-)

+0

Cualquier macro que _no separe su expansión es un problema. En mi humilde opinión, debería ser tarea de la macro garantizar su propia seguridad de uso, no el trabajo de la macro llamada. –