casting issue with realpath function (c programming) - c

When I compile the following code:
#define _POSIX_C_SOURCE 200112L
#define _ISOC99_SOURCE
#define __EXTENSIONS__
#include <stdio.h>
#include <limits.h>
#include <stdlib.h>
int
main(int argc, char *argv[])
{
char *symlinkpath = argv[1];
char actualpath [PATH_MAX];
char *ptr;
ptr = realpath(symlinkpath, actualpath);
printf("%s\n", ptr);
}
I get a warning on the line that contains the call to the realpath function, saying:
warning: assignment makes pointer from integer without a cast
Anybody know what's up? I'm running Ubuntu Linux 9.04

This is very simple. Glibc treats realpath() as a GNU extension, not POSIX. So, add this line:
#define _GNU_SOURCE
... prior to including stdlib.h so that it is prototyped and known to to return char *. Otherwise, gcc is going to assume it returns the default type of int. The prototype in stdlib.h is not seen unless _GNU_SOURCE is defined.
The following complies fine without warnings with -Wall passed:
#include <stdio.h>
#include <limits.h>
#define _GNU_SOURCE
#include <stdlib.h>
int
main(int argc, char *argv[])
{
char *symlinkpath = argv[1];
char actualpath [PATH_MAX];
char *ptr;
ptr = realpath(symlinkpath, actualpath);
printf("%s\n", ptr);
return 0;
}
You will see similar behavior with other popular extensions such as asprintf(). Its worth a look at /usr/include/ to see exactly how much that macro turns on and what it changes.

The compiler doesn't know what realpath is, so it assumes it's a function returning int. It does this for historical reasons: a lot of older C programs relied on it doing this.
You're probably missing the declaration of it, e.g. by forgetting to #include its header file.

Related

How to copy/convert a char string to a wchar_t string in C?

I looked around, and found a program where swprintf is used from the <wchar.h> library. However i tried that method, and it didn't work. It just says program.exe has stopped working when i run the program. I copied the sample program i found, into my own compiler-- which didn't work either. I'll copy the program below:
#include <stdio.h>
#include <wchar.h>
int main(void)
{
wchar_t NameBuffer[100];
char *str1 ="c:\\Program Files\\test.txt";
swprintf(NameBuffer,100,L"%s",str1);
printf("%s\n",NameBuffer);
return 0;
}
Is there something wrong with this code or is it my compiler?
Try converting with mbstowcs():
#include <stdio.h>
#include <wchar.h>
#include <stdlib.h>
int main(void)
{
wchar_t NameBuffer[100];
char *str1 ="c:\\Program Files\\test.txt";
mbstowcs(NameBuffer, str1, 100);
wprintf(L"%ls\n",NameBuffer);
return 0;
}
In the code above, in the printf line
printf("%s\n",NameBuffer);
NameBuffer is not a (converted) value of type char * and therefore you invoke Undefined Behaviour by not matching the %s and its corresponding argument.
Try
wprintf(L"%ls\n", NameBuffer);
or
printf("%ls\n", NameBuffer);
You may also want to define str1 as pointer to const
const char *str1 = "c:\\Program Files\\test.txt";

Why we can get offset of a struct like this?

Today I got some information that we can get the offset of a field in structure this way:
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
struct sdshdr {
int len;
int free;
};
int main(int argc, char* argv[])
{
printf("%d\n", &sdshdr::len);
printf("%d\n", &sdshdr::free);
}
Although I got warnings at compile time, it can successfully run.
How can we explain this? I didn't get information when I searched the web.
Can anyone help explain what happened here?
compilation arguments: gcc -g -O2 -Wall -o main.o main.cpp
Code you showed is not a C-compliant code. These constructions
&sdshdr::len and &sdshdr::free are not valid C constructions.
It seems you compiled the code as a C++ code.
If you want to know the offset of a data member of a structure in C then you should use standard macro offsetof declared in header <stddef.h>
For example
#include <stdio.h>
#include <stddef.h>
struct sdshdr {
int len;
int free;
};
int main(void)
{
printf( "offset of len is equal to %zu\n", offsetof( struct sdshdr, len ) );
printf( "offset of free is equal to %zu\n", offsetof( struct sdshdr, free ) );
return 0;
}
The program output might look like
offset of len is equal to 0
offset of free is equal to 4
If you mean C++ then these expressions
&sdshdr::lenand&sdshdr::free` denote pointers to data members within the structure.

How to pointer reference dynamic sized pointer to array?

I want to be able to reference variable sized array with a global pointer. But what kind of pointer do I use that will work with variable sizes of the array? In the example below, assume N will only be known at runtime (could be an argument for example) so compile time solutions won't work.
What I want to achieve:
main.c
some_sort_of_pointer *x;
main()
{
int N=256; //or N=64 or whatever
char (*LC)[N];
LC=malloc(1024);
x=LC;
memcpy(x[2],"hello world",11);
x[0][176]=123;
dostuff();
}
I'm sure there's an easy obvious way to do this but I can't seem to nail it. My first attempt at asking this was a mess so this time I'm hoping it's clear what I want to achieve.
OS Centos 6.5
compiler GCC 4.8 (using C99)
As at compile time the type to be referenced isn't given, a void pointer might help.
However only storing an untyped reference (what void * in fact is is) is not enough, as it is essential to also know the size of the (VL)array. So the latter also needs to be stored globally, as it can not be pulled from the memory referenced.
An example how this can be achieve is given below:
main.h:
#include <stdlib.h> /* for size_t */
struct VLA_descriptor
{
void * p;
size_t s;
}
extern struct VLA_descriptor vla_descriptor;
foo.h:
void foo(void);
foo.c:
#include "main.h"
#include "foo.h
void foo(void)
{
char (*p)[vla_descriptor.s] = vla_descriptor.p;
/* Do something with the VLA reference p. */
}
main.c:
#include "main.h"
#include "foo.h"
struct VLA_descriptor vla_descriptor = {0};
int main(int argc, char ** argv)
{
size_t s = atoi(argv[1]);
char (*p)[s] = malloc(s);
vla_descriptor.p = p;
vla_descriptor.s = s;
foo();
... /* Free stuff and return. */
}
Error checking had been omitted in this example's code for the sake of readability.
With much thanks to #alk (and everyone else who responded) I think I have the closest I'm going to get to what I'm looking for:
void *LC
int LCS;
int main(int argc, char **argv) {
LCS=256;
LC=malloc(1024)
memcpy(((char(*)[LCS])LC)[2],"hello world",11);
((char(*)[LCS])LC)[0][176]=123;
printf("%d %s\n",((char(*)[LCS])LC)[0][176],&((char(*)[LCS])LC)[2]);
}
((char(*)[LCS])LC) is the equivalent of a what I wanted. It's similar to #alk's idea and does require 2 globals but it means I can use it in functions without having to declare a new variable. I've credited #alk with the answer as what he posted gave me 90% of what I needed.
Though if anyone can reduce ((char(*)[LCS])LC) to a single global, I would be excited to see it :)

What is wrong with usage of atof function?

int main()
{
char str[10]="3.5";
printf("%lf",atof(str));
return 0;
}
This is a simple code I am testing at ideone.com. I am getting the output as
-0.371627
You have not included stdlib.h. Add proper includes:
#include <stdio.h>
#include <stdlib.h>
int main()
{
char str[10]="3.5";
printf("%lf",atof(str));
return 0;
}
Without including stdlib.h, atof() is declare implicitly and the compiler assumes it returns an int.
It could be undefined behavior.

usage of strdup

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main()
{
char *s;
s = strdup("foo");
printf("%s\n", s);
getchar();
return 0;
}
Looks pretty harmless, doesn't it ?
But my IDE, which is Dev-C++, gives my the following warning:
warning: assignment makes pointer from integer without a cast
The warning disappears if you would change the code like this:
char *s;
s = (char*)strdup("foo");
Can anyone help me explain this?
You're using Dev-C++, but strdup is not part of the C or C++ standard, it's a POSIX function. You need to define the proper (according to your IDE's documentation) preprocessor symbols in order for strdup to be declared by the header file ... this is necessary in order for the header file not to pollute the name space when included into conforming C or C++ source files.
For a simple portable alternative, consider
char* mystrdup(const char* s)
{
char* p = malloc(strlen(s)+1);
if (p) strcpy(p, s);
return p;
}
Or, if you know strdup is actually in the library, you can copy its declaration from string.h into your own source file or header ... or use the simpler declaration from the man page:
char *strdup(const char *s);
That's not right. strdup returns char * already. Something else is wrong. Probably because you did not include the right header file that declares the true return type for this function.
#include <string.h>
You're missing #include <string.h>. In the absence of function signatures, strdup is assumed by the compiler to return an int, hence the warning.
man strdup
you will get following things
#include<string.h>
char* strdup(const char * s);
so strdup() returns char* there shuld not be any problem
Actually in your case it takes implicit declaration of strdup() so by default return type is int hence you get this warning
Either include<string.h>
or
give forward declaration char* strdup(const char *);
Also don't forget to free(s) in last when all usage are done

Resources