decimal constant is so large that it is unsigned error?
Hi all,
Plz help me fast.. i want to store 11601508835565898551 data into any of integer variable ,since this value is looking large so i have used unsigned long long type but still it is giving warning "as decimal constant is so large that it is unsigned". And after that i also need to store this value in array of char using sprintf(). Please help me how can i copy this large value into integer in gcc. |
Maybe "guint64" type of glib library could do that. Its maximum value (G_MAXUINT64) is 18446744073709551615. But you need a 64-bit platform for using it!
|
What is the language? C?
The warning here does not complain about the variable you store the number in. unsigned long long (at least on i386/x86_64 gcc linux) is large enough to hold the number. The problem is with the integer literal. When you declare a decimal integral literal in C, the compiler treats it as the first integral type that can hold the value, checking in the following order: int, long int, long long int. But your number is so large that it can not fit the signed long long type. To get rid of the warning, define the literal explicitly as unsigned: Code:
unsigned long long i = 11601508835565898551u; |
Quote:
Im writing code in C only. When i tried this warning goes off but but while executing it is giving error. I have put wnat i wanted to do in simple program.. I just want this program to execute. Code:
#include <stdio.h> Value :11601508835565898551 Illegal instruction |
Code:
unsigned char CharData[8]=""; Also, don't forget about the terminating 0. |
Actually i thought 8 byte in enough to store this value. Bt when i change size of char aaraa that Illegal instruction has gone but still i m not getting the expected answer. Ultimately i also need to convert that value to integer..
This is the modified code ,after atoll() i m expecting answer as initial value 11601508835565898551 Code:
#include <stdio.h> Value :11601508835565898551 CharData1 11601508835565898551 CharDate2 9977174359631986687 |
Quote:
Quote:
Quote:
If you use C99, strtoull() might be better suited for the task. Code:
CharData[strlen(CharData)]='\0'; |
Thank You very much.... Now my program is working fine...
Now just for understanding i have one query. As u have told " the number has 20 digits, so you need 20 + 1 = 21 bytes." But i believe since unsigned long long is of 8 byte so this 8+1(for NULL) is enough to hold. And my code is also working fine array size 9. Code:
#include <stdio.h> Value :11601508835565898551 CharData1 11601508835565898551 CharData2 11601508835565898551 |
Quote:
Millgates is correct about the required array size. Quote:
At run time, your program uses 21 bytes of CharData. Since you only allocated 9 bytes, it uses those 9 bytes plus the following 12 bytes. The consequences of using those following 12 bytes depend on what use the compiler assigned to those 12 bytes. The lack of problems you currently see is just an accident caused by the simplicity of your total program combined with arbitrary stack layout choices made by the compiler. |
Quote:
|
Quote:
An example with a hypothetical x86 compiler (this is not a correct description for any compiler settings you are likely to be using, but may be more informative regarding the kinds of accidents involved than a true version would be). The top of the stack frame is the saved ebp and eip of the caller. The compiler might decide on a stack layout in which your 8 byte Data is right below that and CharData right below that and might decide to align CharData on a four byte boundary. If CharData is 9 bytes long, the next 12 bytes are 3 bytes of alignment waste followed by all of Data, followed by the low byte of the saved ebp. So your bug destroys all of Data right after using it for the last time, so you don't notice that aspect, and it clears the low 8 bits of the caller's ebp. The low 4 bits were clear anyway, so there was one chance in 16 that the whole low byte of the saved ebp was already clear, so clearing it again is symptom free. Under the same compiler rules, if CharData were 8 bytes long, there are no longer 3 bytes of alignment waste, so the next 13 bytes are all of Data, and all of the saved ebp (so if the program got as far as the caller of main using ebp, that would crash) but also includes the low byte of the saved eip, which we will assume was not 0. So when main() returns, it doesn't return to the right place, but to the middle of a multi-byte instruction somewhere earlier in the code that called it. That middle of a multi-byte instruction, misinterpreted as the beginning of an instruction, happens to not decode as any legal instruction, causing an illegal instruction fault (which is quite rare for this kind of bug. Usually you get a seg fault, not an illegal instruction, but once you are clobbering parts of your stack frame results are generally unpredictable). |
thanks to all..:)
|
As a brief follow up...
Instead of using sprintf, use snprintf as it takes the size of the buffer as an additional parameter. That way an overflow will not happen, and you will get a more suitable error message. If you want a bit of fun, try rearranging the order of declaration... If you put CharData first you might find that the value gets wiped out. |
Quote:
I tried in x86_64, unoptimized, with gcc 3.4.6 The local variables Data and CharData are allocated in reverse sequence to their declaration. So if Data is declared first, it is allocated last and gets clobbered by overrun from CharData. But when I reverse the sequence and declare Data second, it is allocated below CharData and is not clobbered. Many details would be different in a more current version of gcc, but (based on the asm code from similar bugs others have posted here) I think that detail of allocation sequence is consistent across many versions of gcc. |
All times are GMT -5. The time now is 07:48 AM. |