This is probably and easy one for you guys, but I couldn't find a definitive answer and I just want to be sure I'm not overlooking anything. I have an equation, which I know permits complex solutions, but I've programmed it in C using "double" and/or "float". Does C simply ignore the complex part if I don't use "complex" types? In other words, does it simply return the real part? Will it generate any errors by not using "complex"? Thanks.
There is a 'complex' and an 'imaginary' data type in C. However, since it has only been a few years since it has been introduced, some of the old systems might not support it. So, its best to handle that kind of solutions explicitly.
If you are performing an illegal operation like sqrt(-1), then it will generate an error.
The following post most probably answers your queries better How to work with complex numbers in C?
The documentation for sqrt() (if you read it) tells you it returns a domain error.
You can find this out for yourself with a test case:
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <errno.h>
int main(int argc, char *argv[])
{
double foo = -1.234;
double foo_sqrt = sqrt(foo);
if (errno == EDOM) {
fprintf(stderr, "Error: EDOM - Mathematics argument out of domain of function (POSIX.1, C99)\n");
return EXIT_FAILURE;
}
/* we never get here */
fprintf(stdout, "sqrt(%f) = %f\n", foo, sqrt(foo));
return EXIT_SUCCESS;
}
Then compile and run:
$ gcc -lm -std=c99 -Wall sqrt_test.c -o sqrt_test
$ ./sqrt_test
Error: EDOM - Mathematics argument out of domain of function (POSIX.1, C99)
$ echo $?
1
Related
I'm running OS X Sierra and trying to compile a c program that uses strcpy_s, but my installed clang compiler is using the c99 standard, but from what I've read strcpy_s requires c11.
Here's the code I'm trying to compile
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(void)
{
char source[] = "Test string";
char destination[50];
if(strcpy_s(destination, sizeof(destination), source))
printf("string copied - %s",destination);
return 0;
}
And here's the command I'm using to compile
$ clang copytest.c -o copytest
copytest.c:11:5: warning: implicit declaration of function 'strcpy_s' is invalid in C99 [-Wimplicit-function-declaration]
if(strcpy_s(copied_string, sizeof(copied_string), source))
^
1 warning generated.
Undefined symbols for architecture x86_64:
"_strcpy_s", referenced from:
_main in copytest-e1e05a.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
I've tried compiling with the standard flag...
clang -std=c11 copytest.c -o copytest
but I get the same exact "invalid in c99" warning. I've also tried compiling with gcc instead, and I still get the same c99 warning.
I tried upgrading via homebrew which shows the following
Warning: gcc 9.2.0 is already installed and up-to-date
I have clang version 9.0.0
$ clang -v
Apple LLVM version 9.0.0 (clang-900.0.39.2)
My xcode version is Xcode 9.2, which from everything I've read should come with c11 support.
Am I doing something wrong with the compiling, is my code itself incorrect? This is the only similar question I found on here, but it didn't even have an answer. Thanks
The _s functions are an optional component of the 2011 C standard (Annex K), and, to the best of my knowledge, they have never been implemented as an integrated part of any C library. Portable code cannot rely on their availability. (Microsoft's C compilers for Windows implement an overlapping set of functions with the same names but different semantics (and sometimes even a different argument list), and at least one bolt-on implementation does exist. See this old answer, and the much longer question and answer it links to, for more detail.)
Also, the _s functions do not solve the problem that they were intended to solve (unsafe string handling); it is necessary to put actual thought into a proper fix for each use of strcpy, instead of globally search-and-replacing strcpy with strcpy_s, etc., as was the hope of the authors of Annex K. If you do put appropriate amounts of thought into a proper fix, you won't need any of the _s functions to implement it. For instance, here's a fixed version of your example program:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(void)
{
char source[] = "Test string";
char destination[50];
size_t srclen = strlen(source);
if (srclen + 1 > sizeof destination) {
fprintf(stderr, "string too long to copy - %zu bytes, need %zu\n",
sizeof destination, srclen + 1);
return 1;
} else {
memcpy(destination, source, srclen + 1);
printf("string copied - %s\n", destination);
return 0;
}
}
And here's an even better version:
#define _XOPEN_SOURCE 700
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char **argv)
{
if (argc != 2) {
fprintf(stderr, "usage: ./test 'message of arbitrary length'\n");
return 1;
}
char *destination = strdup(argv[1]);
if (!destination) {
perror("strdup");
return 1;
}
printf("string copied - '%s'\n", destination);
free(destination);
return 0;
}
Therefore: Never use any of the _s functions. If you need to write a program that compiles on Windows with no warnings, put #define _CRT_SECURE_NO_WARNINGS 1 at the top of each file to make MSVC stop giving you bad advice.
If all, or even most, programmers wrote the suggested solutions above all the time, then these functions wouldn't be needed. We have a lot of evidence that many programmers do not write such careful code, going back to Spaf's notes on the Robert T Morris finger worm in the late 1980's.
You also would prefer not to have to duplicate 10 lines of code for every call site of strcpy. That leads to unreadable code. More so, what zwol suggests is really just an implementation of the function he claims we don't need. A good programmer would take that, stick it in a header, and name it something helpful, maybe checked_strcpy? Or even strcpy_s?
The second suggested implementation, which is purportedly better is not - it would cause an allocation when we might already have a buffer. Allocations are expensive, using this approach everywhere would be bad for perf. It also introduces new complexity because now we'd have to free every duplicated string - imagine doing that with repeated calls to strcat.
There is a fairly nicely done cross-platform implementation here:
https://github.com/intel/safestringlib
I'm also not sure whether this is actually any different, but worth taking a look - https://github.com/coruus/safeclib
I'm creating a cross-system application. It uses, for example, the function itoa, which is implemented on some systems but not all. If I simply provide my own itoa implementation:
header.h:115:13: error: conflicting types for 'itoa'
extern void itoa(int, char[]);
In file included from header.h:2:0,
from file.c:2:0,
c:\path\to\mingw\include\stdlib.h:631:40: note: previous declaration of 'itoa' was here
_CRTIMP __cdecl __MINGW_NOTHROW char* itoa (int, char*, int);
I know I can check if macros are predefined and define them if not:
#ifndef _SOME_MACRO
#define _SOME_MACRO 45
#endif
Is there a way to check if a C function is pre-implemented, and if not, implement it? Or to simply un-implement a function?
Given you have already written your own implementation of itoa(), I would recommend that you rename it and use it everywhere. At least you are sure you will get the same behavior on all platforms, and avoid the linking issue.
Don't forget to explain your choice in the comments of your code...
I assume you are using GCC, as I can see MinGW in your path... there's one way the GNU linker can take care of this for you. So you don't know whether there is an itoa implementation or not. Try this:
Create a new file (without any headers) called my_itoa.c:
char *itoa (int, char *, int);
char *my_itoa (int a, char *b, int c)
{
return itoa(a, b, c);
}
Now create another file, impl_itoa.c. Here, write the implementation of itoa but add a weak alias:
char* __attribute__ ((weak)) itoa(int a, char *b, int c)
{
// implementation here
}
Compile all of the files, with impl_itoa.c at the end.
This way, if itoa is not available in the standard library, this one will be linked. You can be confident about it compiling whether or not it's available.
Ajay Brahmakshatriya's suggestion is a good one, but unfortunately MinGW doesn't support weak definition last I checked (see https://groups.google.com/forum/#!topic/mingwusers/44B4QMPo8lQ, for instance).
However, I believe weak references do work in MinGW. Take this minimal example:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
__attribute__ ((weak)) char* itoa (int, char*, int);
char* my_itoa (int a, char* b, int c)
{
if(itoa != NULL) {
return itoa(a, b, c);
} else {
// toy implementation for demo purposes
// replace with your own implementation
strcpy(b, "no itoa");
return b;
}
}
int main()
{
char *str = malloc((sizeof(int)*3+1));
my_itoa(10, str, 10);
printf("str: %s\n", str);
return 0;
}
If the system provides an itoa implementation, that should be used and the output would be
str: 10
Otherwise, you'll get
str: no itoa
There are two really important related points worth making here along the "don't do it like this" lines:
Don't use atoi because it's not safe.
Don't use atoi because it's not a standard function, and there are good standard functions (such as snprintf) which are available to do what you want.
But, putting all this aside for one moment, I want to introduce you to autoconf, part of the GNU build system. autoconf is part of a very comprehensive, very portable set of tools which aim to make it easier to write code which can be built successfully on a wide range of target systems. Some would argue that autoconf is too complex a system to solve just the one problem you pose with just one library function, but as any program grows, it's likely to face more hurdles like this, and getting autoconf set up for your program now will put you in a much stronger position for the future.
Start with a file called Makefile.in which contains:
CFLAGS=--ansi --pedantic -Wall -W
program: program.o
program.o: program.c
clean:
rm -f program.o program
and a file called configure.ac which contains:
AC_PREREQ([2.69])
AC_INIT(program, 1.0)
AC_CONFIG_SRCDIR([program.c])
AC_CONFIG_HEADERS([config.h])
# Checks for programs.
AC_PROG_CC
# Checks for library functions.
AH_TEMPLATE([HAVE_ITOA], [Set to 1 if function atoi() is available.])
AC_CHECK_FUNC([itoa],
[AC_DEFINE([HAVE_ITOA], [1])]
)
AC_CONFIG_FILES([Makefile])
AC_OUTPUT
and a file called program.c which contains:
#include <stdio.h>
#include "config.h"
#ifndef HAVE_ITOA
/*
* WARNING: This code is for demonstration purposes only. Your
* implementation must have a way of ensuring that the size of the string
* produced does not overflow the buffer provided.
*/
void itoa(int n, char* p) {
sprintf(p, "%d", n);
}
#endif
int main(void) {
char buffer[100];
itoa(10, buffer);
printf("Result: %s\n", buffer);
return 0;
}
Now run the following commands in turn:
autoheader: This generates a new file called config.h.in which we'll need later.
autoconf: This generates a configuration script called configure
./configure: This runs some tests, including checking that you have a working C compiler and, because we've asked it to, whether an itoa function is available. It writes its results into the file config.h for later.
make: This compiles and links the program.
./program: This finally runs the program.
During the ./configure step, you'll see quite a lot of output, including something like:
checking for itoa... no
In this case, you'll see that the config.h find contains the following lines:
/* Set to 1 if function atoi() is available. */
/* #undef HAVE_ITOA */
Alternatively, if you do have atoi available, you'll see:
checking for itoa... yes
and this in config.h:
/* Set to 1 if function atoi() is available. */
#define HAVE_ITOA 1
You'll see that the program can now read the config.h header and choose to define itoa if it's not present.
Yes, it's a long way round to solve your problem, but you've now started using a very powerful tool which can help you in a great number of ways.
Good luck!
So, I am trying to return from a floating point exception, but my code keeps looping instead. I can actually exit the process, but what I want to do is return and redo the calculation that causes the floating point error.
The reason the FPE occurs is because I have a random number generator that generates coefficients for a polynomial. Using some LAPACK functions, I solve for the roots and do some other things. Somewhere in this math intensive chain, a floating point exception occurs. When this happens, what I want to do is increment the random number generator state, and try again until the coefficients are such that the error doesn't materialize, as it usually doesn't, but very rarely does and causes catastrophic results.
So I wrote a simple test program to learn how to work with signals. It is below:
In exceptions.h
#ifndef EXCEPTIONS_H
#define EXCEPTIONS_H
#define _GNU_SOURCE
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <math.h>
#include <errno.h>
#include <float.h>
#include <fenv.h>
void overflow_handler(int);
#endif // EXCEPTIONS_H //
In exceptions.c
#include "exceptions.h"
void overflow_handler(int signal_number)
{
if (feclearexcept(FE_OVERFLOW | FE_UNDERFLOW | FE_DIVBYZERO | FE_INVALID)){
fprintf(stdout, "Nothing Cleared!\n");
}
else{
fprintf(stdout, "All Cleared!\n");
}
return;
}
In main.c
#include "exceptions.h"
int main(void)
{
int failure;
float oops;
//===Enable Exceptions===//
failure = 1;
failure = feenableexcept(FE_OVERFLOW | FE_UNDERFLOW | FE_DIVBYZERO | FE_INVALID);
if (failure){
fprintf(stdout, "FE ENABLE EXCEPTIONS FAILED!\n");
}
//===Create Error Handler===//
signal(SIGFPE, overflow_handler);
//===Raise Exception===//
oops = exp(-708.5);
fprintf(stdout, "Oops: %f\n", oops);
return 0;
}
The Makefile
#===General Variables===#
CC=gcc
CFLAGS=-Wall -Wextra -g3 -Ofast
#===The Rules===#
all: makeAll
makeAll: makeExceptions makeMain
$(CC) $(CFLAGS) exceptions.o main.o -o exceptions -ldl -lm
makeMain: main.c
$(CC) $(CFLAGS) -c main.c -o main.o
makeExceptions: exceptions.c exceptions.h
$(CC) $(CFLAGS) -c exceptions.c -o exceptions.o
.PHONY: clean
clean:
rm -f *~ *.o
Why doesn't this program terminate when I am clearing the exceptions, supposedly successfully? What do I have to do in order to return to the main, and exit?
If I can do this, I can put code in between returning and exiting, and do something after the FPE has been caught. I think that I will set some sort of flag, and then clear all most recent info in the data structures, redo the calculation etc based on whether or not that flag is set. The point is, the real program must not abort nor loop forever, but instead, must handle the exception and keep going.
Help?
"division by zero", overflow/underflow, etc. result in undefined behaviour in the first place. If the system, however, generates a signal for this, the effect of UB is "suspended". The signal handler takes over instead. But if the handler returns, the effect of UB will "resume".
Therefore, the standard disallows returning from such a situation.
Just think: How would the program have to recover from e.g. DIV0? The abstract machine has no idea about FPU registers or status flags, and even if - what result would have to be generated?
C also has no provisions to unroll the stack properly like C++.
Note also, that generating signals for arithmetic exceptions is optional, so there is no guarantee a signal will actually be generated. The handler is mostly meant to notify about the event and possibly clean up external resources.
Behaviour is different for signals which do not origin from undefined behaviour, but just interrupt program execution. This is well defined as the program state is well-defined.
Edit:
If you have to rely on the program to continue under all circumstances, you hae to check all arguments of arithmetic operations before doing the actual operation and/or use safe operations only (re-order, use larger intermediate types, etc.). One exaple for integers might be to use unsigned instead of signed integers, as for those overflow-behavior is well-defined (wrap), so intermediate results overflowing will not make trouble as long as that is corrected afterwards and the wrap is not too much. (Disclaimer: that does not always work, of course).
Update:
While I am still not completely sure, according to comments, the standard might allow, for a hosted environment at least, to use LIA-1 traps and to recover from them (see Annex H. As these are not necessarily precise, I suspect recovery is not possible under all circumstances. Also, math.h might present additional aspects which have to be carefully evaluated.
Finally: I still think there is nothing gained with such approach, but some uncertainty added compared to using safe algorithms. It would be different, if there wer not so much different components involved. For a bare-metal embedded system, the view might be completely different.
I think you're supposed to mess around with the calling stack frame if you want to skip an instruction or break out of exp or whatever. This is high voodoo and bound to be unportable.
The GNU C library lets you use setjmp() outside of a signal handler to which you can longjmp() from inside. This seems like a better way to go. Here is a self-contained modification of your program showing how to do it:
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <setjmp.h>
#include <math.h>
#include <errno.h>
#include <float.h>
#include <fenv.h>
sigjmp_buf oh_snap;
void overflow_handler(int signal_number) {
if (feclearexcept(FE_OVERFLOW | FE_UNDERFLOW | FE_DIVBYZERO | FE_INVALID)){
fprintf(stdout, "Nothing Cleared!\n");
}
else{
fprintf(stdout, "All Cleared!\n");
}
siglongjmp(oh_snap, 1);
return;
}
int main(void) {
int failure;
float oops;
failure = 1;
failure = feenableexcept(FE_OVERFLOW | FE_UNDERFLOW | FE_DIVBYZERO | FE_INVALID);
if (failure){
fprintf(stdout, "FE ENABLE EXCEPTIONS FAILED!\n");
}
signal(SIGFPE, overflow_handler);
if (sigsetjmp(oh_snap, 1)) {
printf("Oh snap!\n");
} else {
oops = exp(-708.5);
fprintf(stdout, "Oops: %f\n", oops);
}
return 0;
}
I am using go-hdf5 to read an hdf5 file into golang. I am on windows7 using a pretty recent copy of mingw and hdf5 1.8.14_x86 and it seems like trying to use any of the predefined types doesn't work, let's focus for example on T_NATIVE_UINT64. I have reduced the issue to the following, which basically leaves go-hdf5 out of the problem and points at something quite fundamental going wrong:
package main
/*
#cgo CFLAGS: -IC:/HDF_Group/HDF5/1.8.14_x86/include
#cgo LDFLAGS: -LC:/HDF_Group/HDF5/1.8.14_x86/bin -lhdf5 -lhdf5_hl
#include "hdf5.h"
#include <stdio.h>
void print_the_value2() { printf("the value of the constant is %d\n", H5T_NATIVE_UINT64); }
*/
import "C"
func main() {
C.print_the_value2()
}
You obviously need to have hdf5 and point the compiler at the headers/dlls and running go get, then executing prints this on my pc
the value of the constant is -1962924545
Running variations of the above, in how/where the constant is read, will give different answers for the value of H5T_NATIVE_UINT64. However I am pretty sure that is none are the right value and in fact trying to use a type with the id returned doesn't work, unsurprisingly.
If I write and run a "real" C program, I get different results
#include <stdio.h>
#include "hdf5.h"
hid_t _go_hdf5_H5T_NATIVE_UINT64() { return H5T_NATIVE_UINT64; }
int main()
{
printf("the value of the constant is %d", _go_hdf5_H5T_NATIVE_UINT64());
}
Compiling using
C:\Temp>gcc -IC:/HDF_Group/HDF5/1.8.14_x86/include -LC:/HDF_Group/HDF5/1.8.14_x86/bin -lhdf5 -lhdf5_hl -o stuff.exe stuff.c
and running gives me
the value of the constant is 50331683
And that appears to be the right value as I can use it directly from my go program. Obviously I want to be able to use the constants instead. Any idea why this could be happening?
Extra info following comments below:
I looked for the definition of H5T_NATIVE_UINT64 in the hdf5 headers and see the following
c:\HDF_Group\HDF5\1.8.14_x86\include>grep H5T_NATIVE_UINT64 *
H5Tpkg.h:H5_DLLVAR size_t H5T_NATIVE_UINT64_ALIGN_g;
H5Tpublic.h:#define H5T_NATIVE_UINT64 (H5OPEN H5T_NATIVE_UINT64_g)
H5Tpublic.h:H5_DLLVAR hid_t H5T_NATIVE_UINT64_g;
The whole header is here
http://www.hdfgroup.org/ftp/HDF5/prev-releases/hdf5-1.8.14/src/unpacked/src/H5Tpublic.h
Thanks!
H5T_NATIVE_UINT64 is NOT a constant but a #define that ultimately evaluates to (H5Open(), H5T_NATIVE_UINT64_g), which cgo does not understand.
It's easy to check by turning on debug output on gcc's preprocessor:
gcc -E -dM your_test_c_file.c | grep H5T_NATIVE_UINT64
Result:
#define H5T_NATIVE_UINT64 (H5OPEN H5T_NATIVE_UINT64_g)
Now the same for H5OPEN:
gcc -E -dM test_go.c | grep '#define H5OPEN'
gives:
#define H5OPEN H5open(),
Right now, cgo does understand simple integer constant defines like #define VALUE 1234, or anything that the gcc preprocessor will turn into an integer constant. See the function func (p *Package) guessKinds(f *File) in $GOROOT/src/cmd/cgo/gcc.go.
I have a strange problem with fabs function in C code. I have two double values and I want to find the absolute value of their difference using code like this:
a = 87.967498;
b = 218.025015;
if (fabs(a-b)<2.0)
...code to execute
The value of fabs(a-b) is an int and is equal to 1. I don't know whats the problem here and I can't find anything on the net. Any help would be great!!
You didn't include <math.h>. Add the following line to your other includes:
#include <math.h>
In order to find such errors easier I recommend you to use verbose compiler warnings (gcc -Wall -Wextra ... if you use gcc).
The only way that fabs could return an int is either:
Your program uses a declaration of fabs other than the version declared in math.h.
Your program failed to include math.h and so does not declare fabs at all. In which case parameters and return values default to int. Which is of course an error because the actual implementation of fabs does not match and so the value returned is nonsense.
See this code:
#include <math.h>
#include <stdio.h>
int main()
{
float a = 87.967498;
float b = 218.025015;
float diff = a-b;
printf("diff=%f\nfabs(diff)=%f\n",diff,fabs(diff));
if (fabs(diff)<2.0) {
printf("OK\n");
} else {
printf("FAIL\n");
}
return 0;
}
It produces this output:
diego#malti:~/tmp$ clang test-math.c -o test-math -lm
diego#malti:~/tmp$ ./test-math
diff=-130.057510
fabs(diff)=130.057510
FAIL
See? The application is OK, the diff (218-87=130), which is not smaller then 2.
See also then when I am compile, I also link -lm to get the mathematical library. The same syntax applies for gcc, I just love using clang :)