473,395 Members | 1,532 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,395 software developers and data experts.

How should I create verbose error information description

Hello, I'm a novice C++ programmer and now I have the task of converting
a number of C++ functions to C. Some of the functions I'm converting takes a
parameter
of type reference-to-std::string that stores verbose error information if an
error occurs in
the function.

How should I implement that in C? A pointer to a fixed-size array of chars
runs the risk
of overflowing. Having the function take a char** and allocate memory as
necessary
seems a poor idea too...reallocations might be needed and the user must
remember that
deallocate.

Any suggestions?

/ Eric
Nov 14 '05 #1
9 2660
In article <co**********@news.island.liu.se>,
Eric Lilja <er*******************@yahoo.com> wrote:
Hello, I'm a novice C++ programmer and now I have the task of converting
a number of C++ functions to C. Some of the functions I'm converting takes a
parameter
of type reference-to-std::string that stores verbose error information if an
error occurs in
the function. How should I implement that in C? A pointer to a fixed-size array of chars
runs the risk
of overflowing. Having the function take a char** and allocate memory as
necessary
seems a poor idea too...reallocations might be needed and the user must
remember that
deallocate.

Any suggestions?


I assume that you need to dynamically generate the verbose error
information; otherwise just taking a char** and pointing the char*
it points to at a string literal will work:
--------
if(errstring)
*errstring="Verbose error information";
--------

If you can put a reasonable upper bound on the length of the information
you need to return, you can statically allocate a buffer and return a
pointer to that:
--------
if(errstring)
{
/*static means it will stick around after we return, which is what we
want.
Note that this also means the caller will need to extract any
useful information before calling this code again, as another
error will overwrite it.
*/
static char errbuf[BIG_ENOUGH];

/*Using snprintf just to be paranoid
Note that snprintf is new in C99. It's also available as a GNU
extension, with different return value semantics (return value
isn't used here, so the difference won't cause problems).
If snprintf isn't available, check your maximum format length more
carefully and use sprintf.
*/
snprintf(errbuf,BIG_ENOUGH,"Verbose error info: foo is %d, bar is %g",foo,bar);
*errstring=errbuf;
}
--------

If you don't have a way to know at compile time how long the string
can get, you'll need to somehow allocate memory for it at run time.
Keeping a static pointer to that buffer in your code (similar to just
keeping a static buffer) will let the caller not need to worry about
deallocating it, as you can recycle it (resizing it if necessary) the
next time you need it.
dave

--
Dave Vandervies dj******@csclub.uwaterloo.ca
I'd better change my domain then; I'm in .net, and I'm physically
somewhere on the Net; it's far too easy for folks to guess *that*.
--Anthony de Boer in the scary devil monastery
Nov 14 '05 #2

"Dave Vandervies" wrote:> In article <co**********@news.island.liu.se>,
Eric Lilja <er*******************@yahoo.com> wrote:
Hello, I'm a novice C++ programmer and now I have the task of converting
a number of C++ functions to C. Some of the functions I'm converting takes
a
parameter
of type reference-to-std::string that stores verbose error information if
an
error occurs in
the function.

How should I implement that in C? A pointer to a fixed-size array of chars
runs the risk
of overflowing. Having the function take a char** and allocate memory as
necessary
seems a poor idea too...reallocations might be needed and the user must
remember that
deallocate.

Any suggestions?


I assume that you need to dynamically generate the verbose error
information; otherwise just taking a char** and pointing the char*
it points to at a string literal will work:
--------
if(errstring)
*errstring="Verbose error information";
--------

If you can put a reasonable upper bound on the length of the information
you need to return, you can statically allocate a buffer and return a
pointer to that:
--------
if(errstring)
{
/*static means it will stick around after we return, which is what we
want.
Note that this also means the caller will need to extract any
useful information before calling this code again, as another
error will overwrite it.
*/
static char errbuf[BIG_ENOUGH];

/*Using snprintf just to be paranoid
Note that snprintf is new in C99. It's also available as a GNU
extension, with different return value semantics (return value
isn't used here, so the difference won't cause problems).
If snprintf isn't available, check your maximum format length more
carefully and use sprintf.
*/
snprintf(errbuf,BIG_ENOUGH,"Verbose error info: foo is %d, bar is
%g",foo,bar);
*errstring=errbuf;
}
--------

If you don't have a way to know at compile time how long the string
can get, you'll need to somehow allocate memory for it at run time.
Keeping a static pointer to that buffer in your code (similar to just
keeping a static buffer) will let the caller not need to worry about
deallocating it, as you can recycle it (resizing it if necessary) the
next time you need it.
dave

--
Dave Vandervies dj******@csclub.uwaterloo.ca
I'd better change my domain then; I'm in .net, and I'm physically
somewhere on the Net; it's far too easy for folks to guess *that*.
--Anthony de Boer in the scary devil monastery


Thanks for your input, Dave. Pondering my alternatives here...the thing
is that I need to make this thread-safe and that rules out any static
variables,
I guess. And having the user call free() after each time he/she calls a
function,
wanting detailed error information seems cumbersome for the user. I guess
I have to make sure the error information generated never exceeds a certain
size and really point out in the documentation that this function requires a
buffer
of at least x amout of bytes.

/ Eric
Nov 14 '05 #3

"Eric Lilja" <er*******************@yahoo.com> wrote in message
news:co**********@news.island.liu.se...

"Dave Vandervies" wrote:> In article <co**********@news.island.liu.se>,
Eric Lilja <er*******************@yahoo.com> wrote:
Hello, I'm a novice C++ programmer and now I have the task of converting
a number of C++ functions to C. Some of the functions I'm converting
takes a
parameter
of type reference-to-std::string that stores verbose error information if
an
error occurs in
the function.

How should I implement that in C? A pointer to a fixed-size array of
chars
runs the risk
of overflowing. Having the function take a char** and allocate memory as
necessary
seems a poor idea too...reallocations might be needed and the user must
remember that
deallocate.

Any suggestions?


I assume that you need to dynamically generate the verbose error
information; otherwise just taking a char** and pointing the char*
it points to at a string literal will work:
--------
if(errstring)
*errstring="Verbose error information";
--------

If you can put a reasonable upper bound on the length of the information
you need to return, you can statically allocate a buffer and return a
pointer to that:
--------
if(errstring)
{
/*static means it will stick around after we return, which is what we
want.
Note that this also means the caller will need to extract any
useful information before calling this code again, as another
error will overwrite it.
*/
static char errbuf[BIG_ENOUGH];

/*Using snprintf just to be paranoid
Note that snprintf is new in C99. It's also available as a GNU
extension, with different return value semantics (return value
isn't used here, so the difference won't cause problems).
If snprintf isn't available, check your maximum format length more
carefully and use sprintf.
*/
snprintf(errbuf,BIG_ENOUGH,"Verbose error info: foo is %d, bar is
%g",foo,bar);
*errstring=errbuf;
}
--------

If you don't have a way to know at compile time how long the string
can get, you'll need to somehow allocate memory for it at run time.
Keeping a static pointer to that buffer in your code (similar to just
keeping a static buffer) will let the caller not need to worry about
deallocating it, as you can recycle it (resizing it if necessary) the
next time you need it.
dave

--
Dave Vandervies dj******@csclub.uwaterloo.ca
I'd better change my domain then; I'm in .net, and I'm physically
somewhere on the Net; it's far too easy for folks to guess *that*.
--Anthony de Boer in the scary devil monastery


Thanks for your input, Dave. Pondering my alternatives here...the thing
is that I need to make this thread-safe and that rules out any static
variables,
I guess. And having the user call free() after each time he/she calls a
function,
wanting detailed error information seems cumbersome for the user. I guess
I have to make sure the error information generated never exceeds a
certain
size and really point out in the documentation that this function requires
a buffer
of at least x amout of bytes.

/ Eric


Unfortunately, snprintf() wasn't available on one of the two compilers I
have to
work with so I guess I have to write something that mimics its behaviour.
Some
strings are of known length, some are generated during runtime by calling os
layer
api functions.

/ Eric
Nov 14 '05 #4
Eric Lilja wrote:
"Dave Vandervies" wrote:> In article <co**********@news.island.liu.se>,
Eric Lilja <er*******************@yahoo.com> wrote:
Hello, I'm a novice C++ programmer and now I have the task of converting
a number of C++ functions to C. Some of the functions I'm converting takes
a
parameter
of type reference-to-std::string that stores verbose error information if
an
error occurs in
the function.

How should I implement that in C? A pointer to a fixed-size array of chars
runs the risk
of overflowing. Having the function take a char** and allocate memory as
necessary
seems a poor idea too...reallocations might be needed and the user must
remember that
deallocate.

Any suggestions?


I assume that you need to dynamically generate the verbose error
information; otherwise just taking a char** and pointing the char*
it points to at a string literal will work:
--------
if(errstring)
*errstring="Verbose error information";
--------

If you can put a reasonable upper bound on the length of the information
you need to return, you can statically allocate a buffer and return a
pointer to that:
--------
if(errstring)
{
/*static means it will stick around after we return, which is what we
want.
Note that this also means the caller will need to extract any
useful information before calling this code again, as another
error will overwrite it.
*/
static char errbuf[BIG_ENOUGH];

/*Using snprintf just to be paranoid
Note that snprintf is new in C99. It's also available as a GNU
extension, with different return value semantics (return value
isn't used here, so the difference won't cause problems).
If snprintf isn't available, check your maximum format length more
carefully and use sprintf.
*/
snprintf(errbuf,BIG_ENOUGH,"Verbose error info: foo is %d, bar is
%g",foo,bar);
*errstring=errbuf;
}
--------

If you don't have a way to know at compile time how long the string
can get, you'll need to somehow allocate memory for it at run time.
Keeping a static pointer to that buffer in your code (similar to just
keeping a static buffer) will let the caller not need to worry about
deallocating it, as you can recycle it (resizing it if necessary) the
next time you need it.


Thanks for your input, Dave. Pondering my alternatives here...the thing
is that I need to make this thread-safe and that rules out any static
variables,
I guess. And having the user call free() after each time he/she calls a
function,
wanting detailed error information seems cumbersome for the user. I guess
I have to make sure the error information generated never exceeds a certain
size and really point out in the documentation that this function requires a
buffer
of at least x amout of bytes.


Another possibility might be to let the caller provide
both a pointer to a `char' array and the array's size, then
use snprintf() to generate the message directly into the
caller's buffer. If the buffer is too short the caller gets
a truncated message

frammis.c line 327: giving up after -2147483648 wa

.... but nothing worse happens.

--
Er*********@sun.com
Nov 14 '05 #5

"Eric Sosman" wrote:
Eric Lilja wrote:
"Dave Vandervies" wrote:> In article <co**********@news.island.liu.se>,
Eric Lilja <er*******************@yahoo.com> wrote:

Hello, I'm a novice C++ programmer and now I have the task of converting
a number of C++ functions to C. Some of the functions I'm converting
takes
a
parameter
of type reference-to-std::string that stores verbose error information
if
an
error occurs in
the function.

How should I implement that in C? A pointer to a fixed-size array of
chars
runs the risk
of overflowing. Having the function take a char** and allocate memory as
necessary
seems a poor idea too...reallocations might be needed and the user must
remember that
deallocate.

Any suggestions?

I assume that you need to dynamically generate the verbose error
information; otherwise just taking a char** and pointing the char*
it points to at a string literal will work:
--------
if(errstring)
*errstring="Verbose error information";
--------

If you can put a reasonable upper bound on the length of the information
you need to return, you can statically allocate a buffer and return a
pointer to that:
--------
if(errstring)
{
/*static means it will stick around after we return, which is what we
want.
Note that this also means the caller will need to extract any
useful information before calling this code again, as another
error will overwrite it.
*/
static char errbuf[BIG_ENOUGH];

/*Using snprintf just to be paranoid
Note that snprintf is new in C99. It's also available as a GNU
extension, with different return value semantics (return value
isn't used here, so the difference won't cause problems).
If snprintf isn't available, check your maximum format length more
carefully and use sprintf.
*/
snprintf(errbuf,BIG_ENOUGH,"Verbose error info: foo is %d, bar is
%g",foo,bar);
*errstring=errbuf;
}
--------

If you don't have a way to know at compile time how long the string
can get, you'll need to somehow allocate memory for it at run time.
Keeping a static pointer to that buffer in your code (similar to just
keeping a static buffer) will let the caller not need to worry about
deallocating it, as you can recycle it (resizing it if necessary) the
next time you need it.


Thanks for your input, Dave. Pondering my alternatives here...the thing
is that I need to make this thread-safe and that rules out any static
variables,
I guess. And having the user call free() after each time he/she calls a
function,
wanting detailed error information seems cumbersome for the user. I guess
I have to make sure the error information generated never exceeds a
certain
size and really point out in the documentation that this function
requires a
buffer
of at least x amout of bytes.


Another possibility might be to let the caller provide
both a pointer to a `char' array and the array's size, then
use snprintf() to generate the message directly into the
caller's buffer. If the buffer is too short the caller gets
a truncated message

frammis.c line 327: giving up after -2147483648 wa

... but nothing worse happens.

--
Er*********@sun.com


Yes, that's another alternative. Seems like an extra argument is worth it so
the user
won't have the remember the value of how small the buffer is allowed to be.
Thank
you for your help.

And, I was wrong before...both compilers I'm working provide extensions that
mimics
the behaviour of C99's snprintf() so I am using a simple preprocessor-macro
in my code
to decide which version should be compiled.

/ Eric
Nov 14 '05 #6
Eric Lilja wrote:
.... snip ...
Unfortunately, snprintf() wasn't available on one of the two compilers I
have to
work with so I guess I have to write something that mimics its behaviour.
Some
strings are of known length, some are generated during runtime by calling os
layer
api functions.


snprintf is a C99 function.

If you limit your line lengths to below 80 (better 65) you will
avoid the ugly effects above.

--
Chuck F (cb********@yahoo.com) (cb********@worldnet.att.net)
Available for consulting/temporary embedded and systems.
<http://cbfalconer.home.att.net> USE worldnet address!
Nov 14 '05 #7
Unfortunately, snprintf() wasn't available on one of the two compilers I
have to
work with so I guess I have to write something that mimics its behaviour.
Some
strings are of known length, some are generated during runtime by calling
os layer
api functions.

/ Eric


You can use this:
printf("%*s", MY_BUF_MAX_SIZE, pcMyBuf);
Nov 14 '05 #8
mef526 wrote:
Unfortunately, snprintf() wasn't available on one of the two compilers I
have to
work with so I guess I have to write something that mimics its behaviour.
Some
strings are of known length, some are generated during runtime by calling
os layer
api functions.

/ Eric


You can use this:
printf("%*s", MY_BUF_MAX_SIZE, pcMyBuf);


Which is completely wrong. The fieldwidth specifies the _minimal_
number of characters written by *printf() for the specified conversion.

What you are looking for is the _precision_ which specifies
the desired upper bound (for %s conversions)
fprintf(stderr, "%.*s", MY_BUF_MAX_SIZE, pcMyBuf);

However, as soon as you do not want to write out possibly truncated
versions of string literals but want to insert additional information,
snprintf() is a good deal easier to use.

-Michael
--
E-Mail: Mine is an /at/ gmx /dot/ de address.
Nov 14 '05 #9
"Eric Lilja" <er*******************@yahoo.com> wrote:
Hello, I'm a novice C++ programmer and now I have the task of converting
a number of C++ functions to C. Some of the functions I'm converting takes a
parameter of type reference-to-std::string that stores verbose error information > if an error occurs in the function. Having the function take a char** and allocate memory as
necessary seems a poor idea too...reallocations might be
needed and the user must remember that deallocate.


The obvious thing to do is to emulate std::string in C code.
The user of the function doesn't need to deallocate anything -
if the C++ code passed a reference then the calling function
is responsible for memory management.

I would start off with something like this:
typedef struct {
char *buf;
size_t capacity;
} STRING;
void STRING_construct(STRING *s, char const *initial_text);
void STRING_destruct(STRING *s);
void STRING_append(STRING const *s);
void STRING_assign(char const *text);

That should cover most of the operations that you'll need.
If you want to get fancy you can maintain a 'size_t len' as well.

Then you don't have to redesign any of the code (and
risk creating new bugs), just replace std::string with
STRING everywhere; call 'construct' after each STRING
is declared, and call 'destruct' at the matching
closing-brace after the construction.
Nov 14 '05 #10

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

7
by: Mick | last post by:
Hi All I'm fairly certain this topic has been discussed before in this forum before, and I would appreciate your patience in this matter. I like XML and use it for various things, but haven't...
7
by: dog | last post by:
I've seen plenty of articles on this topic but none of them have been able to solve my problem. I am working with an Access 97 database on an NT4.0 machine, which has many Access reports. I...
9
by: Marc Miller | last post by:
Hi all, I have 2 dev. machines, the 1st is Win 2000 with .NET 7.0 and the 2nd is XP Pro with .NET 2003. My Web Server is Win 2000 Server with IIS 5.0. I can create a new project on my test...
17
by: Chris Podmore | last post by:
When I perform: EventLog.WriteEntry(strSource, strEntry, EventLogEntryType.Error, intEventID) The event viewer reports The description for Event ID ( 234 ) in Source ( Siclops_WS_Mobile )...
0
by: aartinawani | last post by:
Hi I have an asp.net application running under Windows 2003 Server, IIS 6, for 2 years. Today, suddenly, the site went down at 3:38 pm and the application raised an error entitled "Server too...
5
by: Michael Sperlle | last post by:
Is it possible? Bestcrypt can supposedly be set up on linux, but it seems to need changes to the kernel before it can be installed, and I have no intention of going through whatever hell that would...
0
by: Patrick F | last post by:
I keep getting this error message and i don't know whats the problem is and how to solve it. I have a webproject with 2 components (dll) added to it. One is called PhotoGallery and one is called...
4
by: etuncer | last post by:
Hello All, I have Access 2003, and am trying to build a database for my small company. I want to be able to create a word document based on the data entered through a form. the real question is...
7
by: Mark Carrington | last post by:
I'm developing a web app in .NET 2 using C#, and occasionally see this error, apparently something to do with the theme used on the site: Compiler Error Message: The compiler failed with error...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
0
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.