OK, I've seen this error explained at least 100 times on the net. But in every case, it seems to be an error of #including <string.h> instead of <string> or metioning string instead of std::string. But, I've done all those things. And it still does not work.

By way of background: I am a LONG time newbie C++ programmer (meaning that I write code in spurts and then not at all for several years, which means that whenever I advance beyond newbie status, I slide back after time). I have also traditionally been coding using the old Borland compiler (which works, even if it is ancient, but I like the IDE). I have now been trying to come into the 21st century by using gnu c++ (g++ and mingw). The code problem that I am presenting compiles using the Borland compiler, but gives me the error message only when I try to compile with g++.

The problem code:


#define DOS

#include <string>
#include <time.h>
#include <fstream>
#include <dir.h>
#include <iostream>
#include <stdlib.h>

class ErrorReport
   std::string logfilename;
   void set (const std::string name) {logfilename=name;};
   std::string file() const {return logfilename;};
   std::string GetNow() const
      std::string now;
      char date [10];
      char time [10];
      now= date;
      now+= " ";
      now+= time;
      now+= " ";
      return now;

     . . .

You can see I use std::string and have this header protected with an #ifndef envelope. I am not using namespace in the header, which people tell me is a bad thing to do.

So, any suggestions??

Thanks for your time.

The C standard headers time.h and stdlib.h should not be used in C++ code. You need to using the C++ versions of these headers, which are included with #include <ctime> and #include <cstdlib>, respectively. Then, any function from these headers must also be prefixed with std:: like all other C++ standard library classes and functions.

Then, the _strdate and _strtime functions are not standard C/C++ functions. They are C functions provided by old Microsoft headers (included by time.h), and you should not use them if you want to write portable code (e.g., be able to use another compiler or OS beside Microsoft or Borland). The standard C++ equivalent of that code is this for example (using the strftime function):

char buf[100];
/* Print today's date and time, e.g. "Thu Aug 23 14:55:02 2001". */
std::time_t mytime = std::time(NULL);
std::strftime(buf, 100, "%c", std::localtime(&mytime));
return std::string(buf);

If you look at the documentation for strftime that I linked to, you will find further options for formatting the date / time printout.

While you aren't showing it, I assume you are closing the #ifndef at the end of the file.

As for why it isn't finding the std::string class, I'm not sure. While I do see something that ought to be a showstopper - the C library headers <time.h> and stdlib.h> should be <ctime>and <cstdlib> in C++, and <dir.h> is specific to the Borland MS-DOS compilers and wouldn't be in MinGW at all AFAIK - I can only guess what the cause of the problem you are describing. Could you please post the error messages so we can take a look at them?

I am not surprised about using the old headers and I will correct that, but I do not think that this is the source of my current problem. Yes, I do close the #ifdef at the end of the file. I am only showing the sart of the file, since that is where the current errors are being reported.

The actualy error message (first among many) that I get is:

ErrorHandler.h:49:23: error: 'string' does not name a type
ErrorHandler.h:49:31: error: ISO C++ forbids declaration of 'line' with no type [-fpermissive]
ErrorHandler.h:67:25: error: 'string' has not been declared

On lines 49 and 67, you probably just forgot the std:: when you used string. And the "C++ forbids declaration of line with no type" is probably due to the error above it (that it doesn't recognize 'string' as a type, and therefore, 'line' has no type).

Two pieces of advice:

  1. Check the switches being passed to g++ by your Makefile or IDE, and make sure that it includes Wall (all warnings) as one of the defaults. The compiler will highlight a lot more problems with the code than it would without it. If you are just compiling from the command line, be sure to add that switch to the invocation.

    $ g++ -Wall myprogram.cpp -o myprogram.exe

  2. If your editor or IDE has a regex replace function (such as the M-% of Emacs fame), try a search for lines begining with the word string and find any that need to be changed to std::string. For most regex search functions, the expression would be simply $string or possibly $\w*string depending on how it interprets whitespace.