2016-07-18 14 views
-1

私はstrtoul機能を使用しようとしていますが、それ以下のように予期しない値(付加初めでのFFの)戻っている:strtoulを与える予期しない出力

#include <stdio.h> 
#include <string.h> 
#include <limits.h> 

main() { 
    unsigned long temp ; 
    char *err; 
    temp = strtoul("3334444444",&err,10); 
    if (temp > UINT_MAX) { 
     printf("%lx %x %x\n",temp,3334444444,UINT_MAX); 
    }else 
     printf("%lx %x\n",temp,3334444444); 
} 

$./a.out 
ffffffffc6bf959c c6bf959c ffffffff 

上記の出力があることif部分に対応します確かに、私はelseの部分がここで実行されることを期待しています。なぜ誰もstrtoulがこのように振る舞っている理由を説明できますか?なぜc6bf959cではなくffffffffc6bf959cが返されますか?上記のコードで"3334444444"ではなく"333444444"(つまりわずか4分の1)を使用すると、else部分に対応する正しい出力(つまり13dff55c 13dff55c)が得られます。

Note : As pointed by melpomene in his reply below, stdlib.h header file should have been included and that will resolve the issue. Can anyone please let me know what is being done by the program by assuming the incorrect return type (int in this case) during compile time which can't be undone (or atleast it is not getting undone in this case) even after knowing the correct return type (unsigned long in this case) during link time ? In short, i want to know how c6bf959c is getting converted to ffffffffc6bf959c because of prototype not provided.

+0

あなたはstrtoulの代わりにstrtoullを試しましたか? – bruceg

+0

私はこのコードで期待される動作を得ています。あなたの環境は何ですか? –

+0

'ULONG_MAX'は、32ビットシステムでは' UINT_MAX'と同じサイズです。 bruegが言ったように、 'strtoull'は良いでしょう。 – yellowantphil

答えて

6

警告とgccであなたのコードを有効にしてコンパイルすると得られます。

try.c:5:1: warning: return type defaults to ‘int’ [-Wimplicit-int] 
main() { 
^~~~ 
try.c:5:1: warning: function declaration isn’t a prototype [-Wstrict-prototypes] 
try.c: In function ‘main’: 
try.c:8:12: warning: implicit declaration of function ‘strtoul’ [-Wimplicit-function-declaration] 
    temp = strtoul("3334444444",&err,10); 
      ^~~~~~~ 
try.c:8:5: warning: nested extern declaration of ‘strtoul’ [-Wnested-externs] 
    temp = strtoul("3334444444",&err,10); 
    ^~~~ 
try.c:10:22: warning: format ‘%x’ expects argument of type ‘unsigned int’, but argument 3 has type ‘long long int’ [-Wformat=] 
     printf("%lx %x %x\n",temp,3334444444,UINT_MAX); 
        ^
try.c:12:22: warning: format ‘%x’ expects argument of type ‘unsigned int’, but argument 3 has type ‘long long int’ [-Wformat=] 
     printf("%lx %x\n",temp,3334444444); 
        ^

主な問題は、あなたが忘れてしまったので、関数が宣言(したがってintを返すと仮定)されていないことを示す、implicit declaration of function ‘strtoul’です〜#include <stdlib.h>。不足している#includeを追加すると、tempの値が修正されます。

また、printfについて報告された警告を見て、それらを修正する必要があります。

+1

また、(通常の)32ビットシステムでは、 'temp> UINT_MAX'は決して真ではありません。 – yellowantphil

+0

@melpomene:stdlib.hヘッダーファイルが含まれている必要があることに同意しました。コンパイル時に間違った戻り値(この場合はint)を仮定することによって、プログラムによって何が行われているのかを知らせてもらえますか?それを知った後でさえ、元に戻すことはできません。リンク時に正しい戻り値(この場合は符号なし)? – mezda

+0

@yellowantphil:それが決して真実ではない理由について少し説明できますか? tempは符号なしlongであり、uint_maxより大きい場合があります。 unsigned longは32ビットシステムでも8バイトになります。右 ?? – mezda

関連する問題