2012-02-21 23 views
7

El siguiente código funciona de manera diferente en 64 bits y en 32 bits, lo que me está causando problemas para portar mi código.strtok en máquinas de 64 bits

char * tmp = "How are you?"; 
printf("size of char * = %ld and size of strtok return val = %ld \n",sizeof(char *),sizeof(strtok(tmp," "))); 

A continuación se presenta la salida:

32 bit: 
size of char * = 4 and size of strtok return val = 4 

64 bit: 

size of char * = 8 and size of strtok return val = 4 

La página del manual de strtok dice:

#include <string.h> 

    char *strtok(char *str, const char *delim); 

RETURN VALUE 
     The strtok() and strtok_r() functions return a pointer to the next token, or NULL if there are no more tokens. 

Se supone que el char * en una máquina de 64 bits a ser de 8 bytes como impresa. Entonces, ¿por qué Strtok devuelve un puntero de 4 bytes en una máquina de 64 bits?

Gracias

+2

¿Qué compilador está utilizando para obtener estos resultados? – Joel

+5

¿Has olvidado incluir ''? Entonces el compilador podría estar en el estado de ánimo tradicional y asumir el tipo de retorno 'int' para las funciones que no conoce. –

+2

Confirmado en 'gcc-4.5.real (Ubuntu/Linaro 4.5.2-8ubuntu4) 4.5.2'. Loca. – sarnold

Respuesta

9

que se olvidó de #include <string.h>.

Esto está ocasionando que el compilador infiera el tipo de retorno predeterminado de int. Al # incluir el archivo de encabezado correcto, el prototipo correcto se lleva al alcance.

Esto me resuelve el problema en gcc. Si no es así, ¿qué compilador estás usando?

+1

Su compilador * debería * al menos advertirle si intenta llamar a una función no declarada. Si no es así, debe averiguar cómo aumentar su nivel de advertencia. (La regla int implícita fue eliminada del lenguaje por el estándar ISO C de 1999). Y en un comentario, el OP dice que incluyó 'string.h'; si es así, ese no es el problema. –

+0

Perdón por el problema. Tenía una copia de string.h en mi jerarquía de archivos. Eliminé el string.h y dejé que gcc tomara la ruta predeterminada. Ahora funciona. @ Daniel, Clark: ¡¡¡Gracias por la pista !! – ntalli

+0

@ntalli: la directiva include debe ser '#include ', * not * '#include" string.h "'; eso debería evitar tomar un encabezado 'string.h' de su propia jerarquía de archivos. Y definitivamente debes arreglar la cadena de formato 'printf', como describí en mi respuesta. Compila con 'gcc -std = c99 -pedantic -Wall -Wextra' para obtener mejores advertencias. (Reemplace '-std = c99' con' -ansi' si desea el código C89/C90 en lugar de C99.) –

3

Calling strtok(tmp, " ") causaría un comportamiento indefinido, ya que intente modificar la cadena literal que tmp puntos a - pero ya que el operando de sizeof no se evalúa (con una excepción que no se aplica aquí), eso no es una problema.

El problema real es que está intentando imprimir valores size_t con un formato "%ld", que requiere un argumento unsigned long.

Si su aplicación lo admite, el formato correcto para un argumento size_t es "%zu" (añadido en C99):

printf("size of char * = %zu and size of strtok return val = %zu\n", 
     sizeof(char *), sizeof(strtok(tmp," "))); 

De lo contrario, convertir explícitamente los argumentos al tamaño adecuado. Yo usaría "%lu", ya que size_t es un tipo sin firmar.

printf("size of char * = %lu and size of strtok return val = %lu\n", 
     (unsigned long)sizeof(char *), (unsigned long)sizeof(strtok(tmp," "))); 

Aquí es un completo programa autónomo que debe producir los resultados esperados en cualquier C89 o posterior aplicación:

#include <stdio.h> 
#include <string.h> 
int main(void) { 
    char * tmp = "How are you?"; 
    printf("size of char * = %lu and size of strtok return val = %lu\n", 
      (unsigned long)sizeof(char *), 
      (unsigned long)sizeof(strtok(tmp," "))); 
    return 0; 
} 

EDIT: comentario del OP en la otra respuesta indica que el string.h encabezado fue el problema; Aparentemente había

#include "string.h" 

en lugar de

#include <string.h> 

Voy a dejar esta respuesta aquí porque describe otro problema que necesita ser arreglado en el código del OP, aunque no el que causó la síntoma observado y el compilador recogió el archivo de encabezado string.h incorrecto.

+0

Me encantaría saber la excepción a 'sizeof()' que no se aplica aquí. :) – sarnold

+0

No puedo creer que un especificador de formato incorrecto haga que un valor de 8 se imprima como 4 cuando ambos, que se espera que pasen, son enteros de 64 bits. –

+0

@sarnold ¿Matrices de longitud variable? –

Cuestiones relacionadas