sirven simbolo signo que parentesis para matematicas los llaves ejemplos corchetes c linux segmentation-fault printf comma-operator

simbolo - para que sirven los corchetes en matematicas



falla de segmentación cuando se usan corchetes dobles con printf (3)

#include<stdio.h> #define POOLNAME_FMT "Hello" void main() { printf((POOLNAME_FMT "Cannot allocate %d bytes" POOLNAME_FMT "in pool not enough memory",5)); }

¿Por qué da error de segmentación cuando uso corchetes dobles con printf ? es decir, printf(( )); ?


Está utilizando el operador de coma sin darse cuenta:

( ... "in pool not enough memory",5) ^

dado que el operador de coma evaluará su operando izquierdo y descartará el resultado, y luego evaluará y devolverá el operando correcto, usted terminará con:

printf( 5 ) ;

que intentará convertir un int a un const char *restrict para la cadena de formato, que seguramente no apuntará a la memoria válida. Sin el () , el , habría sido un separador para los argumentos de la función.

The () es una expresión en este contexto; si miramos el borrador del estándar C99 sección 6.5.1 Expresiones primarias , tenemos:

( expression )

por lo tanto , el , se trata como un operador, mientras que podemos ver desde la sección 6.5.2 operadores de Postfix :

postfix-expression ( argument-expression-listopt ) argument-expression-list: assignment-expression argument-expression-list , assignment-expression ^

El , es solo un separador en una llamada de función.

Tener las advertencias habilitadas debería haber ayudado aquí, gcc me da algunas advertencias para este programa:

advertencia: el operando de la izquierda de la expresión de coma no tiene efecto [-Wunused-value]

y

advertencia: pasar el argumento 1 de ''printf'' hace puntero desde entero sin un molde [habilitado por defecto] nota: esperado ''const char * restring'' pero el argumento es de tipo ''int''


Esto se debe a que printf es una función que aceptará sus argumentos en paréntesis únicos, y el segundo conjunto de paréntesis está realmente abriendo una subexpresión:

(string "string" string "string" , 5)

Las primeras cuatro cadenas se concatenan en tiempo de compilación, produciendo:

("string", 5)

Esto luego se evalúa:

  • "string" evalúa como un puntero al primer carácter de la misma
  • a , b evalúa primero, luego arroja el resultado, luego evalúa y devuelve b
  • 5 evalúa a una constante entera 5

Entonces, en efecto, estás llamando:

printf(5);

(Esto es porque la cadena no tiene efectos secundarios).

Algo como esto, sin embargo, funcionaría:

printf((POOLNAME_FMT "Cannot allocate %d bytes" POOLNAME_FMT "in pool not enough memory"),5);

Observe cómo se movieron la coma y los cinco fuera de la subexpresión entre paréntesis.


Porque (a, b) es en realidad un solo valor. Calcula b y devuelve el valor de b .

Entonces, lo que estás haciendo es básicamente:

/* calculate before `,` and ignore */ POOLNAME_FMT "Cannot allocate %d bytes" POOLNAME_FMT "in pool not enough memory"; /* call printf with after `,` */ printf(5);

Lo cual está claramente mal.

Cuando escribe func(a, b) como una llamada a función, C sabe enviar a y b como argumentos separados a func . Cuando dice func((a, b)) , está diciendo explícitamente que (a, b) es un valor y que el resultado (es decir, el valor de b ) se debe enviar a func como un único argumento.

Si compila con advertencias, y si su compilador es amable con usted, podría advertirle sobre esto. Si su compilador no es bueno, todavía debe quejarse de que está dando un int donde se espera un const char * .

Si usa gcc , recomiendo compilar con -Wall , always.