aligned_alloc return assignment warning - c

I am cleaning up warnings and found the following error:
warning: assignment makes pointer from integer without a cast buf = aligned_alloc(ALIGN_VALUE,BUF_SZ);
This call is at the very top of the function, essentially:
char* buf;
buf = aligned_alloc(ALIGN_VALUE,BUF_SZ);
It is my understanding that aligned_alloc returns a void *. If cast the return from aligned_alloc to a (char *) I get:
warning: cast to pointer from integer of different size [-Wint-to-pointer-ast] buf = (char*)aligned_alloc(ALIGN_VALUE,BUF_SZ);
The only thing that seems to fix it is
buf = (char*)(uintptr_t)aligned_alloc(ALIGN_VALUE,BUF_SZ);
I have made sure that I am including stdlib.h to avoid implicit declarations referred to in another post. I assumed the cast to char pointer should have resolved this. I am not understanding why the cast to uintptr_t resolves it when void* and uintptr_t are equivalent as far as I understand.
The following is an example of the structure of the file
#include <syslog.h>
#include <linux/fs.h>
#include <linux/hdreg.h>
#include <sys/ioctl.h>
#include <sys/mman.h> // mmap
#include <sys/time.h>
#include <unistd.h>
#include <stddef.h>
#include <stdint.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <stdio.h>
#include <pthread.h>
void* ax_read_thread(void* arg)
{
fprintf(stderr, "read thread started\n");
ax_priv* priv = (ax_priv*)arg;
char* buf;
uint32_t count = 0;
size_t len, transferred = 0;
buf = (char*)(uintptr_t)aligned_alloc(ALIGN_VALUE,BUF_SZ);
if (buf == NULL){
fprintf(stderr, "Aligned alloc failed\n");
pthread_exit(NULL);
}
while(1){
//do things
}
}
Thank you for all of the help. I see now that the warning is a result of not indicating the proper version when invoking the compiler.

This answer largely summarizes the observations and suggestions from the comments thread, including mine and many others', and wraps them in a bit of expository prose.
In the first place, the problem arises because when you build your program with your present toolchain, in its current form, the aligned_alloc() function is not explicitly declared. In the absence of a declaration, the compiler is inferring its signature: it guesses that the function returns int, and that its parameter types are those obtained via the default argument promotions applied to the types of the actual arguments. The compiler then warns you that those inferences -- especially the return type -- seem inconsistent with how you're actually using the function.
The solution, supposing that the function is available in your C library at all, is to ensure that a correct prototype is provided. You could insert the prototype manually, but you shouldn't. Since it's a standard library function, you should get its declaration from the appropriate header, which for this function is stdlib.h.
HOWEVER, this particular function is new in C11, and evidently you're using a version of GCC that defaults to compiling for an earlier standard. Glibc supports that in part by protecting functions that are new in C11 with a feature-test macro, _ISOC11_SOURCE. This is for your protection: in the event that you're building code written for an earlier standard, and that code happens to provide is own function with the same name as one of C11's new functions, the feature-test system prevents you from suffering a name collision.
If you are indeed writing for C11, as seems to be the case, and if your version of gcc has an option to support C11 (i.e. -std=c11 and/or -std=gnu11), then compiling with that option enabled is your best alternative. If you happen to have a version of Glibc that provides aligned_alloc() but not a version of the compiler that supports a C11 mode, then you have the alternative of manually ensuring that the needed feature test macro is defined to the compiler before any of the standard headers are included. You can do that via a #define at the top of your source file, or via a command-line option to the compiler (e.g. -D_ISOC11_SOURCE=1).
Glibc does have aligned_alloc() from at least version 2.17 (but I think from as early as 2.16). GCC does have a C11 mode since at least version 4.8. If your versions of these components are at least that recent, then it should be sufficient to add the option -std=c11 (to omit GNU extensions) or -std=gnu11 (to support GNU extensions) to your compilation command:
gcc -std=c11 my_program.c

Related

Dev C++ strtok_s throws [Warning] assignment makes pointer from integer without a cast

I have the following program:
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char *argv[])
{
char *tp = NULL, *cp = NULL, *next_token = NULL;
char TokenListe[] = "Hello,I Am,1";
tp = strtok_s(TokenListe, ", ", &next_token);
printf(tp);
return 0;
}
When I compile it with Visual Studio 2015 it compiles, without any warning.
But when I compile it with Dev C++ 5.11 I get the following warning in line 10:
[Warning] assignment makes pointer from integer without a cast
Is there any solution to fix that warning?
Since C11, strtok_s is now standard C, part of the optional "bounds-checking interface" (Annex K). Compilers need not support it.
But if they do, the format is this (C11 K.3.7.3.1):
#define __STDC_WANT_LIB_EXT1__ 1
#include <string.h>
char *strtok_s(char * restrict s1,
rsize_t * restrict s1max,
const char * restrict s2,
char ** restrict ptr);
Any other format is non-standard garbage and should not be used, including Microsoft strtok_s.
Dev C++ is no longer maintained and therefore only contains a very old version of gcc. It does not support C11, but to my knowledge, no newer version of gcc + libraries yet support the C11 bounds-checking interface either. Visual Studio is a non-conforming compiler and can't be used for compiling standard C. Generally, I would advise to use neither of these compilers, but to update to a new version of gcc (for example Codeblocks with Mingw).
Summary: strtok_s cannot be used in sensible ways. Use strtok instead. Simply ensure that all buffers involved are large enough and can't be overrun. In case of a multi-threaded program, simply don't use strtok at all.
If Dev C++ doesn't have the non-standard strtok_s, in C it will be implicitly declared, and assumed to return integer.
Note: strtok_s is in the standard, but as an "optional extension", according to (my free draft copy of the) C11 standard.
You should enable other warnings too, such as the warning for implicit declarations of functions.
If Dev C++ does contain an implementation of strtok_s, and links with it, declaring it yourself might work. But a better option is to find the right header file, or compiler flags, to get it declared, if any such options exist. Consult the documentation.
But note, as Michael Walz commented, that the strtok_s in the C11 standard and Microsoft's strtok_s are different, and don't have the same parameters! I don't know which version Dev C++ implements.
Based on the answer from #thomas-padron-mccarthy, I could fix my problem with declaring the strtok_s function in my header file.
extern char* strtok_s(char*, char*, char**);

How to compile C code on Linux/GCC without deprecated functions being available?

There are old functions such as index, rindex which have now been superseded by strchr and strrchr.
Is there a way to configure the compiler or defines so these functions aren't available?
It can cause confusing warnings when:
accidentally using index name outside of scope for eg - or worse, not warn and use the function in a way that's not intended.
Older GCC versions (4.x) warn when using -Wshadow if you have a variable called index.
See:
http://www.gnu.org/software/libc/manual/html_node/Search-Functions.html#index-index
http://pubs.opengroup.org/onlinepubs/009695399/functions/index.html
Notes:
as #antti-haapala says, the global symbol index shouldn't be redefined since libraries may use it.
This question is regarding the common case when a local variable is called index.
At the time of writing, glibc doesn't mark these functions with the deprecated attribute, so warnings related to using deprecated functions have no effect.
Use the compiler in ISO C mode. The C standard prohibits conforming programs being broken by the presence of identifiers that are not reserved words.
For example, use flags -std=c99.
Sample program:
#include <string.h>
int main()
{
index("abc", 'x');
}
Compiled with -std=c11 -Werror gives:
error: implicit declaration of function 'index' [-Werror=implicit-function-declaration]
You shouldn't redefine these identifiers, as some library that you're linking against could still depend on them existing.
If I understand well, you want to use index as a variable name without conflicting with the index function included in <strings.h>.
In this case you can override using the preprocessor:
#include <stdio.h>
#define index(s, c) deprecated_index(s, c)
#include <strings.h>
int index = 5;
int main(void)
{
printf("%d\n", index);
return 0;
}
Or override index with strchr:
#include <stdio.h>
#include <string.h>
#include <strings.h>
#define index(s, c) strchr(s, c)
int main(void)
{
int index = 5;
char *ptr = index("text", 'x');
printf("%s %d\n", ptr, index);
return 0;
}

stddef.h is included but max_align_t is undeclared

I want to compile this code:
#include <stdalign.h>
#include <stdio.h>
#include <stddef.h>
int main ( int argc , char ** argv )
{
printf ("%zu\n", alignof ( max_align_t ));
return 0;
}
But compiler says that:
error: ‘max_align_t’ undeclared".
stddef.h is included and everything must be ok, isn't it?
P.S. I already tried to compile this code under gcc4.8 and gcc4.9, but I have error as described.
To use a C11 feature you need to tell the compiler to run in C11 compliant mode.
For gcc this can be achieved by specifying the option -std=c11.
I use a compiler that is natively based on c99 that has a stddef.h that it uses. On my computer I need to use the -std=c11 option and also a header file that apparently corresponds to c11.

Undefined reference to memcpy_s

I'm trying to fix an undefined reference to memcpy_s() error. I've included string.h in my file and the memcpy() function works okay, and I've also tried including memory.h. I'm on x64 Windows 7 and using gcc 4.8.1 to compile.
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
void doMemCopy(char* buf, size_t buf_size, char* in, int chr) {
memcpy_s(buf, buf_size, in, chr);
}
memory for buf has been allocated in the main function, which calls doMemCpy(buf, 64, in, bytes). in is a string read from standard input
Exact error from cmd terminal:
undefined reference to "memcpy_s" collect2.exe: error: ld returned 1 exit status
GCC 4.8 does not include the function memcpy_s, or any of the other _s bounds checking functions as far as I can tell. These functions are defined in ISO 9899:2011 Annex K and they are optional to implement. Before using them you must check if __STDC_LIB_EXT1__ is defined.
These functions were originally implemented by Microsoft and many parties objected to including them in the standard. I think the main objection is that the error handling that is done by the functions involves a global callback handle that is shared between threads, but they are also quite inefficient.
Further reading is available from Carlos O'Donell and Martin Sebor in Updated Field Experience With Annex K — Bounds Checking Interfaces.
I've never used this, but AFAIK, you need to add
#define __STDC_WANT_LIB_EXT1__ 1
before
#include <string.h>
to use memcpy_s().

HPUX atof doesn't convert string to double

I'm fetching the version number of an hpux machine and trying to convert it to a float using atof, but this happens:
#include <stdio.h>
#include <sys/utsname.h>
int main(int argc, char *argv[]) {
struct utsname u;
uname(&u);
char* release = u.release;
while (*release != '.')
release++;
release++;
printf("%s\n", release);
printf("%f\n", atof(release));
}
prints this:
# ./test
11.31
0.000000
Returning double 0 just means the conversion failed. The utsname man page says the strings are null terminated, so I don't understand why the atof command is failing. Am I making some kind of obvious mistake here?
The atof function is declared in <stdlib.h>.
If you call it without the required #include <stdlib.h>, the most likely result is that (a) your compiler will print a warning (which you've apparently ignored), and (b) the compiler will assume that atof returns an int result.
Add
#include <stdlib.h>
to the top of your source file. And pay attention to compiler warnings. If you didn't get a warning, find out how to invoke your compiler in a way that makes it warn about this kind of thing. (I don't know what compiler you're using, so I can't offer specifics.) For gcc, the compiler you're using, the -Wall option will enable this warning.
Some background:
Prior to the 1999 edition of the ISO C standard, it was permitted to call a function with no visible declaration. The compiler would assume that the function takes arguments of the (promoted) types passed in the call, and that it returns a result of type int. This typically would work correctly if the function actually does return an int, and if you write the call correctly (and if the function is not variadic, like printf).
The 1999 version of the standard ("C99") dropped the "implicit int" rule, making any call to a function with no visible declaration a constraint violation, requiring a diagnostic (which can be a non-fatal warning). Many compilers, will merely warn about the error and then handle the call under the older rules. And gcc still doesn't enforce C99 rules by default; its default dialect is "GNU90", consisting of the 1990 ISO C standard plus GNU-specific extensions. You can ask it to use C99 semantics with "-std=c99"; to enforce those semantics, you can use "-std=c99 -pedantic" or "-std=c99 -pedantic-errors".
Newer versions of gcc (partially) support the latest 2011 standard if you specify "-std=c11".
See the gcc 4.8.2 manual for details.

Resources