I'm new to coding (currently learning c++ & I know a little of C)...
was reading about functions in math.h and read about errno...
According to the site I referred :-
Domain error (input argument is outside the range in which the operation is mathematically defined, e.g. std::sqrt(-1), std::log(-1), or std::acos(2)). If MATH_ERRNO bit is set, EDOM is assigned to errno. If MATH_ERREXCEPT bit is set, FE_INVALID is raised.
So I tried writing a small program with that knowledge...
#include <iostream>
#include <cerrno>
#include <cmath>
using namespace std;
int main (void)
{
errno = 0;
cout<<"\nWhat I get :-\n";
cout << "log(-3) = " << log(-3) << "\n";
//shouldn't it do (errno = EDOM) in the above step?
cout << "errno = " << errno << "\n";
cout << strerror(errno) << "\n";
errno = EDOM;
cout<<"\nWhat I want :-\n";
cout << "log(-3) = " << log(-3) << "\n";
cout << "errno = " << errno << "\n";
cout << strerror(errno) << "\n\n";
return(0);
}
And in the output I see that the errno is not getting updated to EDOM in my first block even though -3 is not in the domain of log()...
Output:-
What I get :-
log(-3) = nan
errno = 0
Undefined error: 0
What I want :-
log(-3) = nan
errno = 33
Numerical argument out of domain
I don't understand what I'm missing here...
Plz help....
I'm compiling my code on Apple LLVM version 7.3.0 (clang-703.0.31) in Mac.
#define MATH_ERRNO 1 is illegal. You should not redefine standard library symbols. MATH_ERRNO is already defined as 1 by standard.
You cannot set how implementation handles error (aside from compiler-specific switches. Read documentation for your compiler). You can only check it:
if (math_errhandling & MATH_ERRNO)
std::cout << "Error reporting uses errno\n";
else
std::cout << "Error reporting does not use errno\n";
if (math_errhandling & MATH_ERREXCEPT)
std::cout << "Error reporting uses floating-point exceptions\n";
else
std::cout << "Error reporting does not use floating-point exceptions\n";
For clang, relevant flags are -fmath-errno/-fmath-no-errno to use/not use errno.
From discussion on reported bug it seems, that Mac implementation of standard library doesn't use errno at all. So you are out of luck if you want use it for error reporting.
You can find complete example (in C) of math err handling at: http://www.cplusplus.com/reference/cmath/math_errhandling/
For completness example from that site:
#include <stdio.h> /* printf */
#include <math.h> /* math_errhandling */
#include <errno.h> /* errno, EDOM */
#include <fenv.h> /* feclearexcept, fetestexcept, FE_ALL_EXCEPT, FE_INVALID */
#pragma STDC FENV_ACCESS on
int main () {
errno = 0;
if (math_errhandling & MATH_ERREXCEPT) feclearexcept(FE_ALL_EXCEPT);
printf ("Error handling: %d",math_errhandling);
sqrt (-1);
if (math_errhandling & MATH_ERRNO) {
if (errno==EDOM) printf("errno set to EDOM\n");
}
if (math_errhandling &MATH_ERREXCEPT) {
if (fetestexcept(FE_INVALID)) printf("FE_INVALID raised\n");
}
return 0;
}
Related
why is sendfile incompatible with /dev/zero ? why does this code
#include <iostream>
#include <sys/sendfile.h>
#include <fcntl.h>
#include <string.h>
int main(){
int f1 = fileno(tmpfile());
int devzero = open("/dev/zero", O_RDONLY);
if(f1 < 0 || devzero < 0){
throw std::runtime_error("Failed to open files");
}
ssize_t sent = sendfile(f1, devzero, 0, 1);
std::cout << "sent " << sent << " bytes. errno " << errno << " strerror " << strerror(errno) << std::endl;
return 0;
}
consistently output
sent -1 bytes. errno 22 strerror Invalid argument
?
/dev/zero is a special file. It doesn’t represent an on disk file.
From sendfile documentation:
The in_fd argument must correspond to a file which supports mmap(2)-like operations (i.e., it cannot be a socket).
...
EINVAL Descriptor is not valid or locked, or an mmap(2)-like operation is not available for in_fd, or count is negative.
EINVAL out_fd has the O_APPEND flag set. This is not currently supported by sendfile().
These section of kernel source is reporting the error:
if (unlikely(out->f_flags & O_APPEND))
return -EINVAL;
ret = rw_verify_area(WRITE, out, opos, len);
I performed some testing. Reading from a tmpfile(), a regular file, and /dev/zero works. Writing to a regular file works, but writing to /dev/zero fails one of those checks (O_APPEND permissions or rw_verify_area() ).
Edit: Strerror appears to work. E.g., if errno = ERANGE, it outputs "Result too large".
The problem remains that errno is not changed from 0.
In Xcode, I've been trying out cerrno and strerror with the short code below. Xcode returns
sqrt(-1) = nan
Undefined error: 0
instead of
sqrt(-1) = -nan
Numerical argument out of domain,
as does, for example, cpp.sh.
Why is this happening?
#include <iostream>
#include <iomanip>
#include <cmath>
#include <cerrno>
#include <cstring>
using namespace std;
int main() {
errno = 0;
cout << "sqrt(-1) = " << sqrt(-1) << endl;
cout << strerror(errno) << endl << endl;
return(0);
}
Whenever you want to check errno after an operation, you should always check it, and possibly store it, immediately after the operation that sets it. If you perform other function calls in between that check, even something as simple as printing to the terminal, you may be clobbering errno.
One possible reason why errno is becoming 0 is due to the fact that it is wrapped in the stream expressions, and there's no guarantee that iostream does not indirectly set (or unset) errno through its implementation.
If ever you want to check or print the errno reason, you will always want to store the result before you print it. For example:
#include <iostream>
#include <iomanip>
#include <cmath>
#include <cerrno>
#include <cstring>
int main() {
errno = 0;
// store errno immediately after the computation
const auto result = std::sqrt(-1);
const auto err = errno;
// then print
std::cout << "sqrt(-1) = " << result << std::endl;
std::cout << std::strerror(err) << std::endl << std::endl;
return 0;
}
Edit: From the discussions in the OP's comments, this appears to not be the reason for errno not being set -- but rather due to math_errhandling being set to 2. I am keeping this answer here for archival reasons, since the code in the original post could just as easily be seeing this result for the reasons described here.
I'm testing protobuf with zlib compression.
I wrote some c++ sample code using protobuf 3.8.0, but the following error occurred at calling ParseFromZeroCopyStream() at Ubuntu.
terminate called after throwing an instance of 'std::system_error'
what(): Unknown error -1
(core dumped)
what can I do?
I tried to replace ParseFromZeroCopyStream() with ParseFromBoundedZeroCopyStream().
That results in no core dump, but ParseFromBoundedZeroCopyStream() returned false.
test.proto
syntax = "proto2";
package test;
message Msg
{
required uint32 data = 1;
}
test.cc
#include <iostream>
#include <google/protobuf/io/zero_copy_stream_impl.h>
#include <google/protobuf/io/zero_copy_stream_impl_lite.h>
#include <google/protobuf/io/gzip_stream.h>
#include "test.pb.h"
using namespace std;
using namespace google::protobuf;
using namespace test;
int main(void)
{
Msg srcMsg;
srcMsg.set_data(1);
long sSize = srcMsg.ByteSizeLong();
cout << "SerializedSize = " << sSize << endl;
char * compressedMsg = new char[sSize];
io::ArrayOutputStream aos(compressedMsg, sSize);
io::GzipOutputStream gos(&aos);
long cSize;
if (srcMsg.SerializeToZeroCopyStream(&gos) == true)
{
gos.Close();
cSize = aos.ByteCount();
cout << "compression success : " << cSize << " bytes" << endl;
}
else
{
cout << "compression error" << endl;
return 1;
}
Msg targetMsg;
io::ArrayInputStream ais(compressedMsg, cSize);
io::GzipInputStream gis(&ais);
if (targetMsg.ParseFromZeroCopyStream(&gis) == false)
{
cout << "decompression error" << endl;
}
else
{
cout << "decompression success : " << targetMsg.ByteSizeLong() << " bytes" << endl;
cout << "data = " << targetMsg.data() << endl;
}
delete[] compressedMsg;
return 0;
}
I expect that decompression succeeds.
You will need to learn to use a debugger to investigate further why exactly this "unknown error: -1" is thrown - if possible.
That being said, unknown library errors is sometimes caused by a failed memory allocation or in rarer cases some other ressource constraint like failing to start a thread/process, etc.
Hi I am trying to make a directory in windows with this code
header
#include <direct.h>
script
int main() {
string local = "C:/Program Files (x86)/Mail";
try
{
_mkdir (local.c_str ());
cout << "It is made?";
}
catch(invalid_argument& e)
{
cout << e.what () << " " << (char*) EEXIST;
if (e.what () == (char*) EEXIST) {
cout << e.what () << " " << (char*) EEXIST;
}
return;
}
}
The file is clearly not made, but it is also not making the error it should.
_mkdir won't throw an exception. (This is not python or boost, or any smart middleware)
Read the documentation you were referring to: it returns a value. 0 is OK, -1: error, ask why to errno
Don't ignore the return value. You probably have insufficient rights without UAC elevation to create the directory.
So I finally figured errno out, which for errno you need the <errno.h> header. The complete list of errno codes.
If you want to see what errno code something is throwing lets say
if (
_mkdir(((string)"C:/Program Files (x86)/Mail").c_str()) == 0 ||
errno == 17 /* this is the code for - File exists - */
){
// Do stuff
} else {
int errorCode = errno; // You need to save the code before anything else,
// because something else might change its value
cout << errorCode;
}
I wrote this simple program. I know that the printf() function in C returns the total number of characters successfully printed so the following C program works fine because any non-zero value is evaluated as true in C.
#include <stdio.h>
int main(void)
{
if (printf("C"))
return 0;
}
But why does the following C++ program compiles & runs fine? If cout is an object not a function, then why is the program giving the expected output?
#include <iostream>
using namespace std;
int main() {
if (cout << "C++")
// your code goes here
return 0;
}
std::cout << "C++";
is a function call to std::operator<<(std::cout, const char*) which returns a reference to std::cout which is convertible to bool. It will evaluate to true if no error on std::cout occurred.
The << operator returns cout. This is why you can chain the << operator like this:
std::cout << "Hello" << " " << "C++" << " " << "World!" << std::endl;
The returned cout will implicitly conver to the value true in the if.
I'm not exactly sure what you are trying to do but assuming you want your program to exit successfully if and only if the printing succeeded, you should write this in C:
#include <stdlib.h>
#include <stdio.h>
int
main()
{
if(printf("C") < 0)
return EXIT_FAILURE;
return EXIT_SUCCESS;
}
The reason is that printf will return a negative number to report errors and –1 is considered “true” as well.
The corresponding C++ program should look like this:
#include <cstdlib>
#include <iostream>
int
main()
{
if (!(std::cout << "C++"))
return EXIT_FAILURE;
return EXIT_SUCCESS;
}
The reason this works is that calling operator << on std::cout returns a reference to the stream itself, which also is why things like
std::cout << "You've got " << 99 << " points" << std::endl;
work. Each invocation returns a reference to std::cout upon which the next invocation is performed.
Now, std::basic_ios which std::cout is derived from, defines a conversion operator. Since C++11, this is declared as
explicit operator bool() const;
This means that if the stream is evaluated in a boolean context such as as the condition in an if statement, it is converted to a bool. The table at the bottom of the linked page shows under what conditions the returned bool will be true or false. In summary: it will return true unless an error occurred on the stream.
Before C++11 (when we didn't have explicit operators), a void * pointer was returned that was non-NULL if and only if no errors on the stream occurred. And again, a void * pointer can be evaluated in a boolean context.
Be aware that in both programs shown above, the tests could indicate success but the output may still fail. The reason for this is that output is usually buffered inside the program and only if enough output is gathered will the operating system be asked to actually do the output. You can request a flush at any time to make this happen now. In C, you would call fflush on the respective FILE * pointer.
#include <stdlib.h>
#include <stdio.h>
int
main()
{
if(printf("C") < 0 || fflush(stdout) < 0)
return EXIT_FAILURE;
return EXIT_SUCCESS;
}
In C++, you can use the std::flush constant.
#include <cstdlib>
#include <iostream>
int
main()
{
if (!(std::cout << "C++" << std::flush))
return EXIT_FAILURE;
return EXIT_SUCCESS;
}
If you also want a newline, you can use std::endl. Writing
std::cout << "hello, world\n" << std::flush;
has about the same effect as writing
std::cout << "hello, world" << std::endl;
Note however that output buffering is used for performance reasons so if you routinely flush your buffers after each and every output statement, you might well degrade the performance of your program.
Finally, in C++ you can also ask a stream to throw an exception if an error occurs. Since I/O errors should not happen during normal operation and repetitively checking for them can clutter your code, this might come in handy.
#include <cstdlib>
#include <iostream>
int
main()
{
std::cout.exceptions(std::ifstream::failbit);
try
{
std::cout << "C++" << std::flush;
return EXIT_SUCCESS;
}
catch (const std::ios_base::failure &e)
{
return EXIT_FAILURE;
}
}
If you want to test whether your program reports the correct exit status for failed I/O, you can try piping standard output to /dev/full on POSIX systems. /dev/full is a special file that pretends that nothing can be written to it because the file system's capacity is exceeded.
Because this is the same as writing
cout << "C++";
if(cout){
//do whatever
}
It just writes "C++" to cout and checks if your stream is still open.