2012-02-21 79 views
7

以下代码在64位和32位上的工作方式不同,这导致我无法移植我的代码。64位机器上的strtok

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

以下是输出:

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 

的strtok的人页表示:

#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. 

64位机器上的字符*被认为是8个字节作为打印。那么为什么strtok会在64位机器上返回一个4字节的字符指针?

感谢

+2

您使用哪种编译器来获取这些结果? – Joel

+5

你忘记了包含''吗?然后编译器可能会处于传统的情绪状态,并为其不知道的函数假设返回类型为“int”。 –

+2

在'gcc-4.5.real(Ubuntu/Linaro 4.5.2-8ubuntu4)4.5.2'上确认。疯。 – sarnold

回答

9

你忘了#include <string.h>

这导致编译器推断默认返回类型int。通过#include正确的头文件,正确的原型被拉入范围。

这解决了我对gcc的问题。如果它不适合你,你使用的是什么编译器?

+1

如果您尝试调用未声明的函数,您的编译器*应该*至少警告您。如果没有,你需要找出如何提高警戒级别。 (隐式int规则已从1999 ISO ISO标准中的语言中删除。)在评论中,OP说他包含'string.h';如果是这样,那不是问题。 –

+0

对不起。我在我的文件层次结构中有一个string.h的副本。我删除了string.h,让gcc采用默认路径。它现在有效。 @ Daniel,Clark:谢谢你的提示! – ntalli

+0

@ntalli:include指令需要为'#include ',* not *'#include“string.h”';应该避免从你自己的文件层次结构中拾取一个'string.h'头文件。你肯定应该修正'printf'格式的字符串,正如我在我的回答中所描述的那样。用'gcc -std = c99 -pedantic -Wall -Wextra'编译得到更好的警告。 (如果你想要C89/C90代码而不是C99,用'-ansi'替代'-std = c99'。) –

3

调用strtok(tmp, " ")会导致不确定的行为,因为它会尝试修改字符串文字是tmp点 - 但因为sizeof操作数不计算(与在这里并不适用一个例外),这不是一个问题。

真正的问题是,您试图使用"%ld"格式打印size_t值,该格式需要参数unsigned long

如果您的实施支持的话,对于size_t参数的正确格式为"%zu"(C99新增):

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

否则,明确的参数转换成合适的尺寸。我会使用"%lu",因为size_t是一个无符号类型。

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

下面是应该产生的任何C89或更高版本实现预期结果的完全独立的程序:

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

编辑: 的OP对对方的回答评论表明string.h头是问题;显然他有

#include "string.h" 

而不是

#include <string.h> 

我要去,因为它描述了需要被固定在OP的代码,另外一个问题在这里离开这个答案,虽然不是一个引起的观察到的症状。 和编译器拾取错误的string.h头文件。

+0

我很想知道'sizeof()'的例外,这里不适用。 :) – sarnold

+0

我不能让自己相信,一个不正确的格式说明符会导致值8打印为4时,预期传递类型是64位整数。 –

+0

@sarnold可变长度数组? –

相关问题