Troubling converting string to long long in C - c

I'm having trouble getting the atoll function to properly set a long long value in c. Here is my example:
#include <stdio.h>
int main(void) {
char s[30] = { "115" };
long long t = atoll(s);
printf("Value is: %lld\n", t);
return 0;
}
This prints:
Value is: 0
This works though:
printf("Value is: %lld\n", atoll(s));
What is going on here?

First, let's answer your question:
#include <stdio.h>
#include <stdlib.h> // THIS IS WHAT YOU ARE MISSING
int main(void) {
char s[30] = { "115" };
long long t = atoll(s);
printf("Value is: %lld\n", t);
return 0;
}
Then, let's discuss and answer 'why?':
For compatibility with very old C programs (pre-C89), using a function without having declared it first only generates a warning from GCC, not an error (As pointed out by the first comment here, also implicit function declarations are allowed in C89, therefore generating an error would not be appropriate, that is another reason to why only a warning is generated). But the return type of such a function is assumed to be int (not the type specified in stdlib.h for atoll for instance), which is why the program executes unexpectedly but does not generate an error. If you compile with -Wall you will see that:
Warning: Implicit declaration of function atoll
This fact mostly shocks people when they use atof without including stdlib.h, in which case the expected double value is not returned.
NOTE: (As an answer to one of the comments of the question) This is the reason why the results of atoll might be truncated if the correct header is not included.

Related

Visual Studio not returning correct C float values

I am doing some fairly simple math in visual studio 2019 with C, but floats are returning with incorrect values. While debugging I simplified the example down to just a quick return, but something is still off because there's no math included in my example. Is there something missing from my environment?
NOTE: I can return integers with no problem.
#include <stdio.h>
int main() {
float e = simple_float();
printf("after return : %.2f\n", e);
return 0;
}
float simple_float() {
float a = 5.63129;
printf("before return : %.2f\n", a);
return 5.63129;
}
But the output is displaying as such:
This will not even compile if you try gcc/clang. I'm surprised visual C allows this. Does it not have any stricter settings ?
By default, C assumes the return type of any function as ‘int’. So, declare the function prior, which is good practice anyway. Fyi, errors from a C99 compliant compiler:
foo.c:6:14: warning: implicit declaration of function 'simple_float' is invalid in
C99 [-Wimplicit-function-declaration]
float e = simple_float();
^
foo.c:12:7: error: conflicting types for 'simple_float'
float simple_float() {
^
foo.c:6:14: note: previous implicit declaration is here
float e = simple_float();
^
1 warning and 1 error generated.
The Problem with your code is that you are not declaring the function before using it. In that case, the compiler assumes the return type int:
#include <stdio.h>
float foo(void);
int main(void) {
printf("With known prototype : %.2f\n", foo());
printf("Without known prototype : %.2f\n", bar());
return 0;
}
float foo() {
return 5.63129f;
}
float bar() {
return 5.63129f;
}
will output 5.63 in the first line and 0.00 on my machine, compiled with vc. But that seems to depend on the machine.
Compiling this on gcc will result in an error.
Nearly every modern compiler warns about this when compiling and most of them throw an error because the type-check will find a conflict in the actual definition.
I just tried out different compilers, and indeed, there are some compilers that don't regard this as an error. E.g. vc and sdcc just warn the user, but they will generate an output that will result in undefined behaviour.

Own offsetof implementation produces warning

I wrote a small piece of code to understand how the offsetof macro works in the background. Here is the code:
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
/* Getting the offset of a variable inside a struct */
typedef struct {
int a;
char b[23];
float c;
} MyStructType;
unsigned offset = (unsigned)(&((MyStructType * )NULL)->c);
printf("offset = %u\n", offset);
return 0;
}
However, if I run it I get a warning message:
WARNING: cast from pointer to integer of different size [-Wpointer-to-int-cast]
However, if I look at the original offsetof macro in c, the code looks like this:
#include <stdio.h>
#include <stdlib.h>
#include <stddef.h>
int main(void)
{
/* Getting the offset of a variable inside a struct */
typedef struct {
int a;
char b[23];
float c;
} MyStructType;
unsigned offset = offsetof(MyStructType, c);
printf("offset = %u\n", offset);
return 0;
}
So why do I get the warning as I cast to unsigned ? It appears to be the type for the offsetof macro. This is puzzling me.
As mch commented, unsigned is not the right type; it's 32-bit on pretty much all real-world systems. The offsetof macro is supposed to produce a result of type size_t, which is what you "should" be casting to here. I think you're confused by the code you found storing the result into an object of type unsigned; that's okay as long as they're sure the value is small, but it doesn't mean the type of the expression offsetof(MyStructType, c); was unsigned. C allows you to silently assign a larger integer type into a smaller one.
However, no matter what you do, this is not a valid implementation of offsetof and has undefined behavior (via applying -> to an invalid pointer). The way you get a working offsetof without UB is #include <stddef.h>.

syntax error in C prog

I am trying to compile my code with a "C" compiler in my IDE. But don't know what the problem is with these few lines.
the error : syntax error near '='
the errors : '_print': different length of parameter lists and '_print':too many actual parameters
BUT the same code runs perfectly with "C++" compiler. I just get error on "C" compiler.
Can anyone give me any idea about it ?
C does not have function overload, nor default arguments as C++ does, so if you need to handle int and long differently, you will need one function per type, like this:
void print_int(int n, int base);
void print_long(long n, int base);
But in your code, since you are just calling the long version in the int function, you can just have one function:
void print(long n, int base);
and if it is called on int, the argument is automatically promoted to long.
int n = 123;
print(n, 10);

Why won't this C program print the unsigned int?

I wrote this function to reverse a number. I will have test cases that are up to 2^32. I need the function to return unsigned ints. My question is this: why wont this print?
#include <stdio.h>
#include <stdlib.h>
#include<string.h>
unsigned int reverse(unsigned int a);
int main(){
printf("%u\n",reverse(987654321));
//printf("%ui\n",reverse(987654321)); //this wont work either
return 0;
}
unsigned int reverse(unsigned int a)
{
int temp=0;
while(a>0)
{
temp=10*temp+a%10;
a/=10;
}
return temp;
}
Yes I did forget about the proto-type... Bear with me I have been doing Java and Lisp lately. However, my compiler keeps giving me a warning saying I have extra characters in the format string. It also does this if I have type "long long int" and I use "%lli% in the format string, which I also tried.
You forgot to include prototype for your function before main.
unsigned int reverse(unsigned int a);
The number probably is just too big for an unsigned on your architecture.
Remember to always enable maximum warning level for your compiler. This should have told you that reverse is not known where you use it, that you are passing an int to the %u format and also that your number ist too big.

How to determine the length of a function?

Consider the following code that takes the function f(), copies the function itself in its entirety to a buffer, modifies its code and runs the altered function. In practice, the original function that returns number 22 is cloned and modified to return number 42.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define ENOUGH 1000
#define MAGICNUMBER 22
#define OTHERMAGICNUMBER 42
int f(void)
{
return MAGICNUMBER;
}
int main(void)
{
int i,k;
char buffer[ENOUGH];
/* Pointer to original function f */
int (*srcfptr)(void) = f;
/* Pointer to hold the manipulated function */
int (*dstfptr)(void) = (void*)buffer;
char* byte;
memcpy(dstfptr, srcfptr, ENOUGH);
/* Replace magic number inside the function with another */
for (i=0; i < ENOUGH; i++) {
byte = ((char*)dstfptr)+i;
if (*byte == MAGICNUMBER) {
*byte = OTHERMAGICNUMBER;
}
}
k = dstfptr();
/* Prints the other magic number */
printf("Hello %d!\n", k);
return 0;
}
The code now relies on just guessing that the function will fit in the 1000 byte buffer. It also violates rules by copying too much to the buffer, since the function f() will be most likely a lot shorter than 1000 bytes.
This brings us to the question: Is there a method to figure out the size of any given function in C? Some methods include looking into intermediate linker output, and guessing based on the instructions in the function, but that's just not quite enough. Is there any way to be sure?
Please note: It compiles and works on my system but doesn't quite adhere to standards because conversions between function pointers and void* aren't exactly allowed:
$ gcc -Wall -ansi -pedantic fptr.c -o fptr
fptr.c: In function 'main':
fptr.c:21: warning: ISO C forbids initialization between function pointer and 'void *'
fptr.c:23: warning: ISO C forbids passing argument 1 of 'memcpy' between function pointer and 'void *'
/usr/include/string.h:44: note: expected 'void * __restrict__' but argument is of type 'int (*)(void)'
fptr.c:23: warning: ISO C forbids passing argument 2 of 'memcpy' between function pointer and 'void *'
/usr/include/string.h:44: note: expected 'const void * __restrict__' but argument is of type 'int (*)(void)'
fptr.c:26: warning: ISO C forbids conversion of function pointer to object pointer type
$ ./fptr
Hello 42!
$
Please note: on some systems executing from writable memory is not possible and this code will crash. It has been tested with gcc 4.4.4 on Linux running on x86_64 architecture.
You cannot do this in C. Even if you knew the length, the address of a function matters, because function calls and accesses to certain types of data will use program-counter-relative addressing. Thus, a copy of the function located at a different address will not do the same thing as the original. Of course there are many other issues too.
In the C standard, there is no notion of introspection or reflection, thus you'd need to devise a method yourself, as you have done, some other safer methods exists however.
There are two ways:
Disassemble the function (at runtime) till you hit the final RETN/JMP/etc, while accounting for switch/jump tables. This of course requires some heavy analysis of the function you disassemble (using an engine like beaEngine), this is of course the most reliable, but its slow and heavy.
Abuse compilation units, this is very risky, and not fool proof, but if you know you compiler generates functions sequentially in their compilation unit, you can do something along these lines:
void MyFunc()
{
//...
}
void MyFuncSentinel()
{
}
//somewhere in code
size_t z = (uintptr_t)MyFuncSentinel - (uintptr_t)MyFunc;
uint8_t* buf = (uint8_t*)malloc(z);
memcpy(buf,(char*)MyFunc,z);
this will have some extra padding, but it will be minimal (and unreachable). although highly risky, its a lot faster that the disassemble method.
note: both methods will require that the target code has read permissions.
#R.. raises a very good point, your code won't be relocatable unless its PIC or you reassasmble it in-place to adjust the addresses etc.
Here is a standards compliant way of achieving the result you want:
int f(int magicNumber)
{
return magicNumber;
}
int main(void)
{
k = f(OTHERMAGICNUMBER);
/* Prints the other magic number */
printf("Hello %d!\n", k);
return 0;
}
Now, you may have lots of uses of f() all over the place with no arguments and not want to go through your code changing every one, so you could do this instead
int f()
{
return newf(MAGICNUMBER);
}
int newf(int magicNumber)
{
return magicNumber;
}
int main(void)
{
k = newf(OTHERMAGICNUMBER);
/* Prints the other magic number */
printf("Hello %d!\n", k);
return 0;
}
I'm not suggesting this is a direct answer to your problem but that what you are doing is so horrible, you need to rethink your design.
Well, you can obtain the length of a function at runtime using labels:
int f()
{
int length;
start:
length = &&end - &&start + 11; // 11 is the length of function prologue
// and epilogue, got with gdb
printf("Magic number: %d\n", MagicNumber);
end:
return length;
}
After executing this function we know its length, so we can malloc for the right length, copy and editing the code, then executing it.
int main()
{
int (*pointerToF)(), (*newFunc)(), length, i;
char *buffer, *byte;
length = f();
buffer = malloc(length);
if(!buffer) {
printf("can't malloc\n");
return 0;
}
pointerToF = f;
newFunc = (void*)buffer;
memcpy(newFunc, pointerToF, length);
for (i=0; i < length; i++) {
byte = ((char*)newFunc)+i;
if (*byte == MagicNumber) {
*byte = CrackedNumber;
}
}
newFunc();
}
Now there's another bigger problem though, the one #R. mentioned. Using this function once modified (correctly) results in segmentation fault when calling printf because the call instruction has to specify an offset which will be wrong. You can see this with gdb, using disassemble f to see the original code and x/15i buffer to see the edited one.
By the way, both my code and yours compile without warnings but crash on my machine (gcc 4.4.3) when calling the edited function.

Resources