stddef.h is included but max_align_t is undeclared - c

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.

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**);

aligned_alloc return assignment warning

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

Is "small" a keyword in c?

This is the first code
#include <stdio.h>
#include <conio.h>
int main()
{
int small;//showing error-(two or more data type in declaration specifiers
}
This is the second code
#include <stdio.h>
int main()
{
int small;//normal declaration without any error
}
Whenever I include header file <conio.h> then declaring a identifier "small" gives an error, why?
I am using mingw gcc compiler and codeblocks ide
Also I have added following code in <conio.h>
#include <windows.h>
void gotoxy(short int col,short int row)
{
HANDLE hStdout=GetStdHandle(STD_OUTPUT_HANDLE);
COORD position={col,row};
SetConsoleCursorPosition(hStdout,position);
}
after removing above code from <conio.h>
int small;
works even after including <conio.h>.
I guarantee that small is not a keyword in C. If it were, the presence or absence of a #include directive would not make any difference.
The problem is that <windows.h> stupidly defines small as a macro. (Other answers and comments suggest it might be a typedef, but that wouldn't explain the problem you're seeing.)
I'm able to reproduce the problem on my system (Cygwin, Windows 7, compiling with mingw32-gcc, which is installed as part of the Cygwin package). Presumably the same thing would happen with MinGW installed separately from Cygwin.
First of all, <conio.h> is a (non-standard) header provided by the implementation. You almost certainly shouldn't be trying to modify it. You definitely shouldn't be adding a function definition to a header file (function definitions belong in .c files, not in .h files). If you want to write your own gotoxy function, declare it in your own header and define it in your own .c file; don't mess around with the implementation. (B
But when you added your gotoxy function to <conio.h>, you also added
#include <windows.h>
Here's a small program that illustrates the problem:
#include <windows.h>
int main()
{
int small;
}
When I compile this with mingw32-gcc, I get:
c.c: In function 'main':
c.c:4:9: error: two or more data types in declaration specifiers
c.c:4:5: warning: useless type name in empty declaration [enabled by default]
Digging further, it turns out that <windows.h> includes <rpcndr.h>, which contains the following:
#define small char
So every occurrence of the identifier small in any C source that has #include <windows.h> will be replaced by the keyword char -- which, in your case, will cause a syntax error.
A handy way to find things like this: gcc has a -E option that causes it to show the output of the compiler's preprocessor phase. With the above program, I tried this:
$ mingw32-gcc -E c.c | tail
#pragma pack(pop)
# 115 "c:\\gnustep\\bin\\../lib/gcc/mingw32/4.6.1/../../../../include/windows.h" 2 3
# 2 "c.c" 2
int main()
{
int char;
}
$
which shows how the int short; declaration was mangled by the preprocessor.
To be clear, this is entirely the fault of the maintainers of <windows.h> and <rpcndr.h>. small is a perfectly valid C identifier, and a system header absolutely should not define it as a macro. typedef char small; would have served the same purpose and not caused this problem. Others have had similar problems with <windows.h> defining macros min and max. That can be worked around with:
#define NOMINMAX
#include <windows.h>
but as far as I can tell there's no such workaround for small.
Incidentally, rpcndr.h also defines hyper.
The simplest solution is to call your variable something other than small -- and hope you don't collide with other macros defined in <windows.h>. Or you can add
#undef small
before the declaration. You shouldn't need to do either of these things, but thanks to poorly written system headers, such workaround are sometimes necessary.
Or just avoid including <windows.h> (that's not always possible).
(You could modify your copy of the rpcndr.h file, but I advise against doing so; it's likely to cause other problems, and your code still won't compile on a system where rpcndr.h hasn't been hacked.)
UPDATE : This may have been corrected. I don't see the error using x86_64-w64-mingw32-gcc under Cygwin on Windows 10. Perhaps someone else who uses mingw can investigate further.
No. There is no keyword like small in standard C. This may be a macro in <conio.h>.
C11: 6.4.1 Keywords:
keyword: one of
auto
break
case
char
const
continue
default
do
double
else
enum
extern
float
for
goto
if
inline
int
long
register
restrict
return
short
signed
sizeof
static
struct
switch
typedef
union
unsigned
void
volatile
while
_Alignas
_Alignof
_Atomic
_Bool
_Complex
_Generic
_Imaginary
_Noreturn
_Static_assert
_Thread_local
I found it...
its a macro defined in some header file which is included in windows.h.
as i have included windows.h in conio.h so in my program it is automatically included when i include conio.h.
I Found it by ctrl + clicking on small
By adding #include <windows.h>, you are pulling in a lot of other header files. One problem that has been reported is of it defining a preprocessor macro "small". It has also been discussed in another SO question.
One workaround is to add #undef small after you #include <windows.h>.
Just define WIN32_LEAN_AND_MEAN macro in code or VS Properties dialog and the problem will be gone:
#define WIN32_LEAN_AND_MEAN
The error seems to be the fault of MinGW. The same error appears with large.
There is no such keyword, but check if it is typedefed somewhere.

c sscanf and SCNu64 compile error

I don't understand the below error message when I compile this code. I couldn't find out what wrong with it.
Description Resource Path Location
Type expected ‘)’ before ‘SCNu64’.
#include <inttypes.h>
int calc_rate(uint64_t *rate, char val[], char mult[]) {
int rc = sscanf(val, "%" SCNu64 "%2s", rate, mult);
}
If you have both <inttypes.h> and <stdio.h> included, then the code fragment shown compiles cleanly. (You can't call sscanf() legally unless there's a prototype in scope.) That means the problem is in the code prior to what you are showing. Or it means that your compiler doesn't provide support for exactly 64-bit types, which is rather unlikely unless you're on a relatively obscure mainframe, or you aren't compiling in C99 or C11 mode.

why is strtof is always evaluating to HUGE_VAL?

What could be the issue here? It doesn't matter what number I choose for str, it is always 26815615859885194199148049996411692254958731641184786755447122887443528060147093953603748596333806855380063716372972101707507765623893139892867298012168192.00
char *str = "2.6";
printf("%f\n", strtof(str, (char**)NULL));
//prints 26815615859885194199148049996411692254958731641184786755447122887443528060147093953603748596333806855380063716372972101707507765623893139892867298012168192.00
whole program:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main(int argc, char *argv[])
{
char *str = "2.6";
printf("%f\n", strtof(str, NULL));
return 1;
}
compile with -Wall:
test4.c:7: warning: implicit declaration of function âstrtofâ
What platform are you building for/on? The warning that you say is being emitted:
test4.c:7: warning: implicit declaration of function âstrtofâ
indicates that the compiler doesn't know that strtof() returns a float, so it's going to push an int to the printf() call instead of a double. strtof() is normally declared in stdlib.h, which you're including. But it wasn't a standard function until C99, so the exact compiler platform (and configuration/options you're using) may affect whether it's being made available or not.
strtof is defined in C99 only. It may be that passing the option -std=c99 to the compiler will fix it since default GCC (-std=gnu89) includes only a few C99 features.
Another option is to use the C89-kosher strtod. Which is probably the better option in the long run, anyways. (When do you need singles except in exceptional circumstances?)
Perhaps you've forgotten to include the correct header(s)?
#include <stdlib.h>
#include <stdio.h>
int main() {
printf("%f\n", strtof("2.6", NULL));
return 0;
}
produces:
2.600000
for me...
Given your warnings, you should try adding -std=c99 to get the C99 standard definitions from the header. By default it will assume that the return value is an int and then try to convert that to a float. This will obviously be wrong. Alternatively you could simply supply your own, correct declaration for strtof().
As the others have said, you need -std=c99. But you can also use strtod() which is string to double, and you don't need -std=c99 for that.
I was having problems with strtof() on CentOS 5.5 with glibc 2.5 unless I used -std=c99, but strtod() worked perfectly.

Resources