[vox-tech] strerror deprecated?

Peter Jay Salzman p at dirac.org
Tue Dec 26 11:51:38 PST 2006


On Tue 26 Dec 06, 10:37 AM, Micah Cowan <micah at cowan.name> said:
> On Tue, 2006-12-26 at 12:30 -0500, Peter Jay Salzman wrote:
> > Hi all,
> > 
> > Trying to write portable/correct code between Linux and MS Visual C++.
> > 
> > The cl.exe compiler is telling me that "strerror() is deprecated".  Is that
> > true?  I never heard such a thing.  Tried Googling and couldn't find any
> > mention of strerror() being deprecated.
> 
> I recently saw a similar message (for some other user: I'm not compiling
> on MS these days) about strncpy(). Rest assured, strerror() is not and
> will not be deprecated.
> 
> > The compiler also told me that strerror() was unsafe.  After thinking about
> > it for a second, I'm guessing it meant "thread unsafe".
> 
> Thread unsafe... I'm starting to think they're going to issue that
> warnign for anything that's actually portable and in the standard
> library...
> 
> > Lastly, the compiler told me that I should use strerror_s() which is more
> > safe.
> 
> Same for strncpy(): strncpy_s().
> 
> > I looked at the prototype for this function and it requires a buffer,
> > the buffer's length, and the errno.  Passing a char * to be filled by a
> > function when you don't know how large of a buffer that function wants
> > hardly sounds like a good idea.
> 
> Well, since you pass the buffer's length, it will probably safely
> truncate the message.
> 
> If it was designed well enough that it works like snprintf(), you could
> pass it a 0 to get the size of the buffer you could pass it.
> 
> > How should this function be used safely?
> > Keep allocating memory until the buffer isn't filled all the way?  Sounds
> > like I would need to write my own strerror function just to make sure the
> > buffer is large enough.  Why would a standards committee do such a thing?
> 
> Oh, they wouldn't. The Standard has absolutely no concept whatever of
> strerror_s() (or indeed, of thread safety). It's an MS-ism.
> 
> > 
> > Lastly, strerror_s doesn't appear in any man pages on my Linux system.
> > However, it does appear to be similar to strerror_r() which my man pages say
> > is POSIX compliant (under a suitable #define).
> 
> I'd forgotten about that. It seems to suffer from the same problem,
> though: no way to determine appropriate string buffer size.
> 
> > What's the quickest fastest way of using strerror_r if on Linux and
> > strerror_s if on Windows?
> 
> Are you writing a threaded program? If not, ignore Windows' broken
> warnings: they're completely bogus. Better yet, find a way to disable
> them.
> 
> If you are, I'd suggest wrapping strerror() with a locking mechanism,
> use plain strerror() to get the static string and check its size, and
> proceed however you like. I'd probably use a snprintf()-style mechanism,
> or perhaps something more like strerrordup().
> 
> I'd start the wrapper with something other than "str" followed by
> lowercase letters, as that's reserved to the implementation.
> str_error_dup() would be fine, though.
 
Thanks, Micah.

I took your advice about disabling that warning.  Here's how.  Put this:

#ifdef __WIN32__
   #define _CRT_SECURE_NO_DEPRECATE
#endif

in the source code file, above the header that declares strerror (or strncpy
as the case may be).



In the Makefile I define __WIN32__ since I'm not using windows.h, which is
where I believe that thing is defined:


   # Uncomment one of these.
   OS = __WIN32__
   # OS = __LINUX__

   TARGET   = One_Loan_API_Demo
   CFILES   = $(wildcard *.cpp)

   ifeq ($(OS),__WIN32__)
      # Don't forget to run vcvars32.bat!
      CC       = cl.exe
      DEBUG    = -Zi
      INCLUDES = -I"C:\Java\jdk1.5.0_10\include" \
         -I"C:\Java\jdk1.5.0_10\include\win32"
      OFILES   = $(patsubst %.cpp, %.obj, $(CFILES))
      LDLIBS   = -link "C:\Java\jdk1.5.0_10\lib\jvm.lib"
      CXXFLAGS = -nologo -EHsc $(INCLUDES) $(DEBUG) -Za -MT -W3 -D$(OS)
   else
      CC       = g++
      DEBUG    = -g3
      INCLUDES =
      OFILES   = $(patsubst %.cpp, %.o, $(CFILES))
      LDLIBS   =
      CXXFLAGS = $(INCLUDES) -Wall -D$(OS)
   endif

   all: $(OFILES)
      $(CC) $(OFILES) $(LDLIBS)

   %.obj : %.cpp
      $(CC) -c $(CXXFLAGS) $<

   .PHONY: clean
   clean:
      rm -rf core $(TARGET).class $(OFILES)


Do you know of a better way to detect Linux/Windows than requiring someone
to comment/uncomment the Makefile?

How the hell did I end up programming on Windows?  :-P

Thanks!
Pete


More information about the vox-tech mailing list