473,385 Members | 1,942 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,385 software developers and data experts.

what is a better style?

Lets say I have a class that is only available if a specific DLL (a.dll) is
present. I can't link to that DLL through lib files or my app will fail on
any machine that doesn't have a.dll.

So I do LoadLibrary()'s and keep function pointers in my wrapper class...
Which is a better style?

DWORD CClass::SomeFunc()
{
if (m_pfn != NULL)
return (*m_pfn)(parm1, parm2);

return (DWORD) -1;
}

or

DWORD CClass::SomeFunc()
{
ASSERT(m_pfn != NULL);
return (*m_pfn)(parm1, parm2);
}

I guess the first version fails "more graciously" if the developer calls it
incorrectly, but the 2nd version isn't returning "made up" return codes and
is more "in your face" during development.
Oct 30 '05 #1
4 2242
Nobody wrote:
Lets say I have a class that is only available if a specific DLL (a.dll) is
present. I can't link to that DLL through lib files or my app will fail on
any machine that doesn't have a.dll.

So I do LoadLibrary()'s and keep function pointers in my wrapper class...
Which is a better style?

DWORD CClass::SomeFunc()
{
if (m_pfn != NULL)
return (*m_pfn)(parm1, parm2);

return (DWORD) -1;
}

or

DWORD CClass::SomeFunc()
{
ASSERT(m_pfn != NULL);
return (*m_pfn)(parm1, parm2);
}

I guess the first version fails "more graciously" if the developer calls it
incorrectly, but the 2nd version isn't returning "made up" return codes and
is more "in your face" during development.


Assertions are used during development to catch "that's not supposed to
happen" errors, such as bad arguments to a function. They disappear
when the program is compiled in "release" mode, so they are of no use
to convey information to users.

Returning error codes (or sometimes throwing exceptions) are common
ways to signal a "valid" error in a program. It is then possible to
display a user-friendly message, recover or fail.

As you can see, both ways are not necessarily exclusives. Actually, it
is common practice to use both assertions and error codes in the same
function. If it is normal (or predictable) for an error to happen, you
should not use (only) assertions to catch them, since you don't want a
user to see them.

Remember to be both user-friendly (try to recover or display an
informative message and fail graciously) and developper-friendly
(convey as much informations you can, such as with compile-time or
run-time assertions).
Jonathan

Oct 30 '05 #2
"Nobody" <no****@cox.net> wrote in message
news:5dV8f.779$5N1.161@dukeread08...
: Lets say I have a class that is only available if a specific DLL
(a.dll) is
: present. I can't link to that DLL through lib files or my app will
fail on
: any machine that doesn't have a.dll.
:
: So I do LoadLibrary()'s and keep function pointers in my wrapper
class...
: Which is a better style?
:
: DWORD CClass::SomeFunc()
: {
: if (m_pfn != NULL)
: return (*m_pfn)(parm1, parm2);
:
: return (DWORD) -1;
: }
This function is ok if a value such as (DWORD)-1 makes sense
and can be interpreted as an error condition by the caller.
But as you mentioned, such an "invalid" result value may not
always exist -- so a separate way to report errors may be needed.

And this is exactly what exceptions are for.
I would actually write this function as:
DWORD CClass::SomeFunc()
{
if( m_pfn == NULL )
throwLibraryNotLoadedError(); // calls throw(..smthg..)
return (*m_pfn)(parm1, parm2);
}

: or
:
: DWORD CClass::SomeFunc()
: {
: ASSERT(m_pfn != NULL);
: return (*m_pfn)(parm1, parm2);
: }

So what happens in release mode, assuming that ASSERT checks
are then disabled, if that function is called when m_pfn==0 ?
You will be getting undefined behavior (hopefully just a
crash of your program).
Can this ever be a good idea ?

: I guess the first version fails "more graciously" if the developer
calls it
: incorrectly, but the 2nd version isn't returning "made up" return
codes and
: is more "in your face" during development.

My approach is to throw an exception if one of the preconditions
of the function is violated (for instance, if no DLL was loaded).
To help with debugging, I may also want to trigger an assertion
failure, breakpoint or warning at debug time (i.e. within the function
throwLibraryNotLoadedError() ).

Ivan
--
http://ivan.vecerina.com/contact/?subject=NG_POST <- email contact
form
Brainbench MVP for C++ <> http://www.brainbench.com

Oct 30 '05 #3

Nobody wrote:
Lets say I have a class that is only available if a specific DLL (a.dll) is
present. I can't link to that DLL through lib files or my app will fail on
any machine that doesn't have a.dll.

So I do LoadLibrary()'s and keep function pointers in my wrapper class...
Which is a better style?

DWORD CClass::SomeFunc()
{
if (m_pfn != NULL)
return (*m_pfn)(parm1, parm2);

return (DWORD) -1;
}

or

DWORD CClass::SomeFunc()
{
ASSERT(m_pfn != NULL);
return (*m_pfn)(parm1, parm2);
}

I guess the first version fails "more graciously" if the developer calls it
incorrectly, but the 2nd version isn't returning "made up" return codes and
is more "in your face" during development.


The difference between these two versions is more than an issue of
style. Each is making a very different statement about the program.
Either one may be correct, but not both.

The first version states that m_pfn could be NULL while this program is
executing; so it is necessary for the program to check for that
possibility and report it to the caller.

The second version states that the program is certain that m_pfn will
never be NULL while it is executing. The program's behavior is
therefore defined only when m_pfn is not NULL. Should that assumption
ever turn out not to be true, then the program's behavior will be
undefined. Ideally the program would crash quickly without causing any
harm.

Greg

Oct 30 '05 #4
Nobody wrote:
Lets say I have a class that is only available if a specific DLL (a.dll) is
present. I can't link to that DLL through lib files or my app will fail on
any machine that doesn't have a.dll.

So I do LoadLibrary()'s and keep function pointers in my wrapper class...
Which is a better style?

DWORD CClass::SomeFunc()
{
if (m_pfn != NULL)
return (*m_pfn)(parm1, parm2);

return (DWORD) -1;
}

or

DWORD CClass::SomeFunc()
{
ASSERT(m_pfn != NULL);
return (*m_pfn)(parm1, parm2);
}

I guess the first version fails "more graciously" if the developer calls it
incorrectly, but the 2nd version isn't returning "made up" return codes and
is more "in your face" during development.


I guess later is better - because not every function returns DWORD that
can be interpreted. Your code has to verify the presence of .dll abefore
calling methods anyway, so you are just duplicating this there.

BTW, in our system we have introduced nice related tool to automatize
generating such wrapper objects. To create such object, we provide
".dli" file with content like (actual example is for Lotus Notes client
..dll)

FN(WORD, OSLoadString, (HMODULE hModule, STATUS StringCode, char
*retBuffer, WORD BufferLength))
FN(WORD, OSTranslate, (WORD TranslateMode, char far *In, WORD
InLength, char far *Out, WORD OutLength))
FN(STATUS, NotesInitExtended, (int argc, char **argv))
FN(STATUS, OSPathNetConstruct, (char *PortName, char *ServerName, char
far *FileName, char *retPathName))
FN(STATUS, NSFDbOpen, (char far *PathName, DBHANDLE far *rethDB))
FN(STATUS, NSFDbClose, (DBHANDLE hDB))
............

- basically, this is somewhat "reparsed" header file for .dll. Then place

#define DLLFILENAME "nnotes.dll"
#define DLIMODULE NOTES
#define DLIHEADER <notes/notes.dli>
#define DLLCALL LNPUBLIC
#include <Core/dli_header.h>

to common header file and

#define DLLFILENAME "nnotes.dll"
#define DLIMODULE NOTES
#define DLIHEADER <notes/notes.dli>
#define DLLCALL LNPUBLIC
#include <Core/dli_header.h>

to some .cpp file.

This creates global function NOTES() returning object instance that has
all .dll functions described in .dli file defined as its methods.
Moreover, it has operator bool that can be used to test whether .dll is
present:

char h[256];
if(NOTES())
NOTES().OSLoadString(GetModuleHandle(NULL), ERR(nError), h, 255);
(http://upp.sf.net)

Mirek
Oct 30 '05 #5

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

Similar topics

220
by: Brandon J. Van Every | last post by:
What's better about Ruby than Python? I'm sure there's something. What is it? This is not a troll. I'm language shopping and I want people's answers. I don't know beans about Ruby or have...
54
by: Brandon J. Van Every | last post by:
I'm realizing I didn't frame my question well. What's ***TOTALLY COMPELLING*** about Ruby over Python? What makes you jump up in your chair and scream "Wow! Ruby has *that*? That is SO...
21
by: PassingBy | last post by:
I recently came across a template site selling cd's and was wondering what the groups opinion is of this? I purchased one of the cd's and the templates are great and Im looking forward to...
7
by: Bura Tino | last post by:
Hi, Going forward, what's better to use <td height="20"> or <td style="height:20;">
145
by: Mark Johnson | last post by:
Oddly enough, I found it difficult, using Google, to find a list of best-of sites based on the quality of their css packages. So I'd ask. Does anyone know of particularly good sites which are in...
12
by: Kevin Blount | last post by:
I'm playing with dragable <DIV>s, being inspired by google.com/ig, where you can move items on the page around and have items you move over change position if necessary. I have 3 div's setup,...
9
by: Jay | last post by:
Everywhere I go (read/browse) I see these parameters.... ByVal sender As Object, ByVal e As System.EventArgs Yet I never see them used within the function/method. Could someone tell me what they...
8
by: clintonG | last post by:
Every single time neophytes or converts ask about naming and style conventions what are they told by the majority consensus? The answer is "do what you prefer but do so consistently" right? Yes,...
49
by: Zach | last post by:
After having taken a looong break from VB (last used 6.0), I started getting back into programming again, this time with VS 2005. I began reading up on VB.NET from various sources (books,...
9
by: tvnaidu | last post by:
This is just small plain HTML program wtote manually (since I am new to web programming, may be some tools I can use I think), this program loaded onto microcontroller with small foot print web...
0
by: aa123db | last post by:
Variable and constants Use var or let for variables and const fror constants. Var foo ='bar'; Let foo ='bar';const baz ='bar'; Functions function $name$ ($parameters$) { } ...
0
by: ryjfgjl | last post by:
If we have dozens or hundreds of excel to import into the database, if we use the excel import function provided by database editors such as navicat, it will be extremely tedious and time-consuming...
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
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?
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
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
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...
0
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,...

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.