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().
Related
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**);
I use polybench kernels. In polybench.c, code has a line as follows:
int ret = posix_memalign (&new, 32, num);
This line makes problem with lli interpreter. I tries to use malloc instead, but I have the same error
LLVM ERROR: Tried to execute an unknown external function: posix_memalign
Is there any other function could be used without having this problem?
You will not be surprised to hear that posix_memalign() is standardized as part of POSIX, not part of standard C. As such, providing that function is not a requirement on conforming C implementations. On the other hand, as part of POSIX, it is widely available.
malloc() promises to return a pointer to memory aligned properly for an object of any type. I'm not sure why you want to ensure an even stronger alignment requirement, but your next best bet for doing so is the aligned_alloc() function, which is standard C since C2011. If your C library conforms to C2011, then you can replace your posix_memalign() call with
#include <stdlib.h>
#include <errno.h>
// ...
new = aligned_alloc(32, num);
int ret = (new ? 0 : errno);
If you don't have aligned_alloc(), either, then your implementation may provide other alternatives, but none of them are standard.
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
I am getting compilation errors when i tried to compile the code as shown below
#include <stdlib.h>
main()
{
int val = 10;
char buff[10];
char *ptr;
ptr = ltoa(val,buff,10);
printf("The val is %s\n",buff);
}
I get the compilation errors shown below:
[mcanj#varaprada ~]$ cc -g samp2.c
samp2.c: In function `main':
samp2.c:8: warning: assignment makes pointer from integer without a cast
samp2.c:11:2: warning: no newline at end of file
/tmp/ccifnKFx.o(.text+0x23): In function `main':
/home/mcanj/samp2.c:8: undefined reference to `ltoa'
collect2: ld returned 1 exit status.
Please let me know how to resolve this issue. Thanks and regards.
It is itoa() and not ltoa() but even itoa() is not a Standard Library function.
If you want your program to be portable use sprintf() or snprintf() in C99.
It's itoa, not ltoa. just change the call and it will be fine.
see http://www.cplusplus.com/reference/clibrary/cstdlib/itoa/
Portability
This function is not defined in ANSI-C and is not part of C++, but is
supported by some compilers.
http://www.strudel.org.uk/itoa/
Arrgghh C/C++! It would appear that itoa() isn't ANSI C standard and doesn't work
with GCC on Linux (at least the version I'm using). Things like this are frustrating especially if you want your code to work on different platforms (Windows/Linux/Solaris/whatever).
C does not have itoa or ltoa functions, C has atoi function that converts a string pointed to to an int representation.
You have to implement the function if you want to use it.
I seem to be able to compile code that calls wsprintf with the MinGW gcc if I have these includes (in this order):
#include <stdarg.h>
#include <wingdi.h>
#include <winuser.h>
But I feel like there might be some "cleaner" way to do this. Perhaps with only a single header inclusion. I arrived at this list by searching header files for missing symbols and then including headers one-by-one.
Include <Windows.h>
Do you mean swprintf()?
swprintf() is described in the C99 standard. You need <wchar.h>.
If wsprintf does the same as swprintf you may want to consider using a standard function instead.
7.24.2.3 The swprintf function
Synopsis
[#1]
#include <wchar.h>
int swprintf(wchar_t * restrict s,
size_t n,
const wchar_t * restrict format, ...);
Description
[#2] The swprintf function is equivalent to fwprintf, except
that the argument s specifies an array of wide characters
into which the generated output is to be written, rather
than written to a stream. No more than n wide characters
are written, including a terminating null wide character,
which is always added (unless n is zero).
Do you mean the standard function swprintf? In that case you should include wchar.h.