473,661 Members | 2,522 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

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...reallocat ions might be needed and the user must
remember that
deallocate.

Any suggestions?

/ Eric
Nov 14 '05 #1
9 2674
In article <co**********@n ews.island.liu. se>,
Eric Lilja <er************ *******@yahoo.c om> 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...reallocat ions 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="Ver bose 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,"Ve rbose error info: foo is %d, bar is %g",foo,bar);
*errstring=errb uf;
}
--------

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**********@n ews.island.liu. se>,
Eric Lilja <er************ *******@yahoo.c om> 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...reallocat ions 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="Ver bose 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,"Ve rbose error info: foo is %d, bar is
%g",foo,bar);
*errstring=errb uf;
}
--------

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.c om> wrote in message
news:co******** **@news.island. liu.se...

"Dave Vandervies" wrote:> In article <co**********@n ews.island.liu. se>,
Eric Lilja <er************ *******@yahoo.c om> 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...reallocat ions 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="Ver bose 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,"Ve rbose error info: foo is %d, bar is
%g",foo,bar);
*errstring=errb uf;
}
--------

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**********@n ews.island.liu. se>,
Eric Lilja <er************ *******@yahoo.c om> 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...reallocat ions 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(errstrin g)
*errstring="Ver bose 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(errstrin g)
{
/*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,"Ve rbose error info: foo is %d, bar is
%g",foo,bar );
*errstring=errb uf;
}
--------

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
deallocatin g 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**********@n ews.island.liu. se>,
Eric Lilja <er************ *******@yahoo.c om> 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...reallocat ions might be needed and the user must
remember that
deallocat e.

Any suggestions?

I assume that you need to dynamically generate the verbose error
informatio n; otherwise just taking a char** and pointing the char*
it points to at a string literal will work:
--------
if(errstring )
*errstring="Ver bose 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,"Ve rbose error info: foo is %d, bar is
%g",foo,bar) ;
*errstring=errb uf;
}
--------

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
deallocati ng 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********@yah oo.com) (cb********@wor ldnet.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.c om> 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...reallocat ions 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_construc t(STRING *s, char const *initial_text);
void STRING_destruct (STRING *s);
void STRING_append(S TRING const *s);
void STRING_assign(c har 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
1564
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 been able to justify its verbose nature especially w.r.t. transmitting information over the wire. (assuming there is no compression involved) All I've been able to come up with is "Oh well, the benefits of using
7
8850
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 want my users to be able to select a report, click on a command button on a form, which will then automatically create the report as a pdf file and save it to the user's machine. I am using Adobe Acrobat (5.0 I think) and have Adobe Distiller as a
9
2298
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 server from the 1st machine, but I receive an 'HTTP/1.1 500 Internal Server error" from my Web Server. My userid/password are the same on all 3 machines.
17
3297
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 ) cannot be found. The local computer may not have the necessary registry information or message DLL files to display messages from a remote computer. I think I need to create a dll that returns error messages for event ID’s.
0
1630
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 busy". Searching the event logs I found an entry for: Event ID: 0 Source:.NET Runtime
5
6765
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 cause. If I could create a large file that could be encrypted, and maybe add files to it by appending them and putting in some kind of delimiter between files, maybe a homemade version of truecrypt could be constructed. Any idea what it...
0
1718
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 Photo. Any suggestions on how to solve this? i can't do much at the moment. Server Error in '/PhotoGallery' Application. -------------------------------------------------------------------------------- Cannot create/shadow copy 'Photo' when...
4
12427
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 this: can Access create the document and place it as an OLE object to the relevant table? Any help is greatly appreciated. Ricky
7
6641
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 code 1. Clicking the "Show Detailed Compiler Output" link on the error page shows a large command line that looks like it's using the vbc compiler to build the auto-generated theme code, but doesn't display any useful error messages. Executing...
0
8343
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can effortlessly switch the default language on Windows 10 without reinstalling. I'll walk you through it. First, let's disable language synchronization. With a Microsoft account, language settings sync across devices. To prevent any complications,...
0
8855
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers, it seems that the internal comparison operator "<=>" tries to promote arguments from unsigned to signed. This is as boiled down as I can make it. Here is my compilation command: g++-12 -std=c++20 -Wnarrowing bit_field.cpp Here is the code in...
0
8758
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven tapestry of website design and digital marketing. It's not merely about having a website; it's about crafting an immersive digital experience that captivates audiences and drives business growth. The Art of Business Website Design Your website is...
0
7364
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing, and deployment—without human intervention. Imagine an AI that can take a project description, break it down, write the code, debug it, and then launch it, all on its own.... Now, this would greatly impact the work of software developers. The idea...
0
4179
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The last exercise I practiced was to create a LAN-to-LAN VPN between two Pfsense firewalls, by using IPSEC protocols. I succeeded, with both firewalls in the same network. But I'm wondering if it's possible to do the same thing, with 2 Pfsense firewalls...
0
4346
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
1
2762
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated we have to send another system
2
1986
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.
2
1743
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence can significantly impact your brand's success. BSMN Consultancy, a leader in Website Development in Toronto offers valuable insights into creating effective websites that not only look great but also perform exceptionally well. In this comprehensive...

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.