0

I have a customized Exception class:

Exception.cc:

#include "Exception.h"


const char* Exception::getMessage()
{
  return strerror(this -> error_code);
}

int Exception::getErrno()
{
  return this -> error_code;
}

Exception::Exception(int errno)
{
  this -> error_code = errno;
}

Exception.hh

#ifndef __EXECPTION_H__
#define __EXECPTION_H__

#include <string.h>

class Exception
{
private:
  int error_code;

public:

    const char* getMessage();

    int getErrno();

  Exception(int errno);
};

#endif

And another customized class Buffer which provides a function to reverse content of a buffer byte by byte:

Buffer.h:

#ifndef __BUFFER_H__
#define __BUFFER_H__

#include <stdlib.h>
#include <cerrno>

class Buffer
{

private:
  char * buffer;
  int size;


public:
    Buffer(int size);
  ~Buffer();
  void reverse();

    friend class File;
};

#endif

Buffer.cc:

#include "Buffer.h"
#include "Exception.h"


Buffer::Buffer(int size)
{
  this -> size = size;
  this -> buffer = (char *)malloc(size);
  if(this -> buffer == NULL)
    throw Exception(errno);
}

Buffer::~Buffer()
{
  if(this -> buffer == NULL)
    free(this -> buffer);
}

void Buffer::reverse()
{
  char tmp;
  int i;
  char * tmpb = this -> buffer;
  for(i = 0; i < this -> size / 2; i++)
  {
    tmp = (char)tmpb[i];
    tmpb[i] = tmpb[size - i - 1];
    tmpb[size - i - 1] = tmp;
  }
}

main.cc

#include "Buffer.h"
#include "Exception.h"
#include <stdlib.h>

#include <iostream>
using namespace std;

int main (const int argc, const char** argv)
{
    if(argc != 3)
    exit(-1);


  return 0;
}

Compiler gives me back errors:

Buffer.cc:10:11: error: no matching conversion for functional-style cast from 'int' to 'Exception'
    throw Exception(errno);
          ^~~~~~~~~~~~~~~
./Exception.h:6:7: note: candidate constructor (the implicit copy constructor) not viable: no known conversion from 'int' to 'const Exception' for 1st
      argument
class Exception
      ^
./Exception.h:17:3: note: candidate constructor not viable: no known conversion from 'int' to 'int (*(*)())' for 1st argument
  Exception(int errno);
  ^
1 error generated.

It looks like the compiler misunderstands throw Exception(errno);. I call a constructor there, why is it taken as a type cast?

JACK M
  • 2,627
  • 3
  • 25
  • 43
  • I know this is not an answer to your question, but why don't you use a vector? You can iterate over it in both directions and probably need not to reverse the buffer. If not, reversing a buffer can be done with STL: https://stackoverflow.com/questions/8877448/how-do-i-reverse-a-c-vector – Jens Nov 14 '16 at 10:12
  • Names with two underscores `__` are reserved by the standard. – Jens Nov 14 '16 at 10:12
  • @PeterT: Buffer.h includes `cerror`. Isn't it the same to errno.h? @Jens: I am newbie to C++. So you see I mix C with C++. – JACK M Nov 14 '16 at 10:16
  • Headers starting with c, e.g. ctsdlib, put all the C stuff in namespace std. So if you want to access errno from cerrno, you have to prefix it with std::. – Jens Nov 14 '16 at 10:20
  • I thought that :-) The problem is that the languages look similar, but the idioms are very difference. Many accepted C practices are discouraged in C++ for good reasons. Depending on you experience as a programmer, I would recommend to read some literature about C++, e.g. https://isocpp.org/tour, or the books from Scott Meyers. There are also the core guidelines which provide good guidance: https://github.com/isocpp/CppCoreGuidelines/blob/master/CppCoreGuidelines.md. – Jens Nov 14 '16 at 10:24

1 Answers1

6

There's no such thing as "calling the constructor". Exception(errno), (Exception)errno and static_cast<Exception>(errno) are all equivalent in your code.

That being said, the root of your problem is something else: you're using the reserved name errno, which is a standard macro (with implementation defined contents). Macros have no regard for C++ scopes, so your constructor declaration is actually

Exception(int whatever_errno_actually_expands_to);

On my gcc, this is actually:

Exception(int (*__errno_location ()));

Solution: don't use reserved names for identifiers.

krzaq
  • 16,240
  • 4
  • 46
  • 61