Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C Programming > Pse, help me to understand this code

Reply
Thread Tools

Pse, help me to understand this code

 
 
__frank__
Guest
Posts: n/a
 
      10-28-2005
The following code use a macro and a label.

I would to change it and use instead
a more readable function and avoid the label.

The macro DAQmxFailed checks for the return code
of the various functions:
DAQmxCreateTask()
DAQmxStartTask()
DAQmxReadAnalogScalarF64()
and others one

If these functions return a int < 0 means
that an error occured so DAQmxGetExtendedErrorInfo
displays info about error.

DAQmxFailed is another macro (defined in NIDAQmx.h):

#define DAQmxFailed(error) ((error)<0)

Taskhandle is a typedef of unsigned long;
float 64 of a __int64 (MS VC++); int32 is a long

Thanks in advance

/***************** Begin ******************* /

#include <stdio.h>
#include "NIDAQmx.h"

#define DAQmxErrChk(functionCall) { if(
DAQmxFailed(error=(functionCall)) ) { goto Error; } }

int main(int argc, char *argv[])
{
int32 error=0;
TaskHandle taskHandle;
float64 value;
char errBuff[2048]={'\0'};

/*********************************************/
/*/ DAQmx Configure Code
/*********************************************/
DAQmxErrChk (DAQmxCreateTask("",&taskHandle));
DAQmxErrChk
(DAQmxCreateAIVoltageChan(taskHandle,"Dev1/ai0","",DAQmx_Val_Cfg_Default,-10.0,10.0,DAQmx_Val_Volts,""));

/*********************************************/
/*/ DAQmx Start Code
/*********************************************/
DAQmxErrChk (DAQmxStartTask(taskHandle));

/*********************************************/
/*/ DAQmx Read Code
/*********************************************/
DAQmxErrChk (DAQmxReadAnalogScalarF64(taskHandle,10.0,&value,0 ));

printf("Acquired reading: %f\n",value);

Error:
if( DAQmxFailed (error) )
DAQmxGetExtendedErrorInfo(errBuff,204;
if( taskHandle!=0 ) {
/*********************************************/
/*/ DAQmx Stop Code
/*********************************************/
DAQmxStopTask(taskHandle);
DAQmxClearTask(taskHandle);
}
if( DAQmxFailed (error) )
printf("DAQmx Error: %s\n",errBuff);
printf("End of program, press Enter key to quit\n");
getchar();
return 0;
}
 
Reply With Quote
 
 
 
 
Flash Gordon
Guest
Posts: n/a
 
      10-28-2005
__frank__ wrote:
> The following code use a macro and a label.
>
> I would to change it and use instead
> a more readable function and avoid the label.


In general I am anti-goto, but for handling exceptional conditions it
can be useful, and that is how it is used here. My main complaint would
be hiding the control statement (goto) within the macro.

> The macro DAQmxFailed checks for the return code
> of the various functions:
> DAQmxCreateTask()
> DAQmxStartTask()
> DAQmxReadAnalogScalarF64()
> and others one
>
> If these functions return a int < 0 means
> that an error occured so DAQmxGetExtendedErrorInfo
> displays info about error.
>
> DAQmxFailed is another macro (defined in NIDAQmx.h):
>
> #define DAQmxFailed(error) ((error)<0)


Traditionally macros are all upper case, e.g.
#define DAQMXFAILED(error) ((error)<0)

This makes it stand out which is important because macros can have
non-obvious effects.

> Taskhandle is a typedef of unsigned long;
> float 64 of a __int64 (MS VC++); int32 is a long
>
> Thanks in advance
>
> /***************** Begin ******************* /
>
> #include <stdio.h>
> #include "NIDAQmx.h"
>
> #define DAQmxErrChk(functionCall) { if( DAQmxFailed(error=(functionCall)) ) { goto Error; } }
>
> int main(int argc, char *argv[])
> {
> int32 error=0;
> TaskHandle taskHandle;
> float64 value;
> char errBuff[2048]={'\0'};


do {

> /*********************************************/
> /*/ DAQmx Configure Code
> /*********************************************/
> DAQmxErrChk (DAQmxCreateTask("",&taskHandle));


error = QmxCreateTask("",&taskHandle);
if (error < 0)
break;

> DAQmxErrChk
> (DAQmxCreateAIVoltageChan(taskHandle,"Dev1/ai0","",DAQmx_Val_Cfg_Default,-10.0,10.0,DAQmx_Val_Volts,""));


error = ......
if (error < 0)
break;

> /*********************************************/
> /*/ DAQmx Start Code
> /*********************************************/
> DAQmxErrChk (DAQmxStartTask(taskHandle));


error = DAQmxStartTask(taskHandle);
if (error < 0)
break;

> /*********************************************/
> /*/ DAQmx Read Code
> /*********************************************/
> DAQmxErrChk (DAQmxReadAnalogScalarF64(taskHandle,10.0,&value,0 ));


error = ......
if (error < 0)
break;

> printf("Acquired reading: %f\n",value);


} while (0);

> Error:


The problem with using a loop and break is when add in other control
structures such as other loops and switch statements since the break
only takes you out of the top most.

Another alternative is to use two functions, one which does the work and
returns on error and the second that calls it and handles clean up. Then
you can do clever things like

int worker(......)
{
... do stuff
if (....)
return -1;
... do stuff
if (....)
return -2;
......
}

int controller(......)
{
int ret = worker(......)
switch (ret) {
case 0: .....
case -1: ....
......
}

Sometimes you would not want breaks between the cases in the above
switch (e.g. if it is just doing clean up) sometimes you would.

Remember that beauty is in the eye of the beholder, so whatever method
you use some people will dislike it. I've used several different methods
depending on the exact circumstances and what I thought would be best in
each case.

> if( DAQmxFailed (error) )


if (error < 0)

> DAQmxGetExtendedErrorInfo(errBuff,204;
> if( taskHandle!=0 ) {
> /*********************************************/
> /*/ DAQmx Stop Code
> /*********************************************/
> DAQmxStopTask(taskHandle);
> DAQmxClearTask(taskHandle);
> }
> if( DAQmxFailed (error) )
> printf("DAQmx Error: %s\n",errBuff);
> printf("End of program, press Enter key to quit\n");
> getchar();
> return 0;
> }

--
Flash Gordon
Living in interesting times.
Although my email address says spam, it is real and I read it.
 
Reply With Quote
 
 
 
 
Richard Bos
Guest
Posts: n/a
 
      10-28-2005
Flash Gordon <> wrote:

> __frank__ wrote:
> > The following code use a macro and a label.
> >
> > I would to change it and use instead
> > a more readable function and avoid the label.

>
> In general I am anti-goto, but for handling exceptional conditions it
> can be useful, and that is how it is used here. My main complaint would
> be hiding the control statement (goto) within the macro.


I agree. Therefore...

> do {
>
> > /*********************************************/
> > /*/ DAQmx Configure Code
> > /*********************************************/
> > DAQmxErrChk (DAQmxCreateTask("",&taskHandle));

>
> error = QmxCreateTask("",&taskHandle);
> if (error < 0)
> break;


> > printf("Acquired reading: %f\n",value);

>
> } while (0);


....this is evil, since you're still in effect using a goto, but you've
hidden it inside a bogus loop construct.
If you _must_ use goto (and sometimes you must, or at least it's the
least bad choice), be up-front about it.

Richard
 
Reply With Quote
 
Jordan Abel
Guest
Posts: n/a
 
      10-28-2005
On 2005-10-28, __frank__ <> wrote:
> /*********************************************/
> /*/ DAQmx Configure Code
> /*********************************************/


What is this? You do realize that if you did a multiline comment in
this style every second line wouldn't be commented, right?
 
Reply With Quote
 
__frank__
Guest
Posts: n/a
 
      10-28-2005
Jordan Abel ha scritto:

> What is this? You do realize that if you did a multiline comment in
> this style every second line wouldn't be commented, right?


Just a copy&paste from a sources provided (together the
acquisition card) with the installation of NI-DAQmx
(drivers/software for NI data-acquistion cards).
 
Reply With Quote
 
__frank__
Guest
Posts: n/a
 
      10-28-2005
Thanks for the preciuos help.
This afternoon I'll try to build first using
the sources provided from the manufacturer (that
seems to be bad written - see Jordan's post below)
then using sources with your suggestions.
Regards,
Frank
 
Reply With Quote
 
Flash Gordon
Guest
Posts: n/a
 
      10-28-2005
Richard Bos wrote:
> Flash Gordon <> wrote:
>
>>__frank__ wrote:
>>
>>>The following code use a macro and a label.
>>>
>>>I would to change it and use instead
>>>a more readable function and avoid the label.

^^^^^^^^^^^^^^^

>>In general I am anti-goto, but for handling exceptional conditions it
>>can be useful, and that is how it is used here. My main complaint would
>>be hiding the control statement (goto) within the macro.

>
> I agree. Therefore...
>
>>do {
>>
>>
>>> /*********************************************/
>>> /*/ DAQmx Configure Code
>>> /*********************************************/
>>> DAQmxErrChk (DAQmxCreateTask("",&taskHandle));

>>
>>error = QmxCreateTask("",&taskHandle);
>>if (error < 0)
>> break;

>
>>> printf("Acquired reading: %f\n",value);

>>
>>} while (0);

>
> ...this is evil, since you're still in effect using a goto, but you've
> hidden it inside a bogus loop construct.
> If you _must_ use goto (and sometimes you must, or at least it's the
> least bad choice), be up-front about it.


The OP wanted to avoid the label, so I told him how it could be done. I
also pointed out some of the problem.

The problem with the goto approach is that, on seeing the label, you
have no bounds on how much of the function you need to check. With the
do loop at least you know the scope is limited to that block within the
function.

I consider neither approach to be ideal and which C had the very limited
exception handling that HP Pascal had, where you could throw an integer
error code and catch it. IIRC it was

TRY
do stuff
IF whatever THEN
ESCAPE(-1)
do stuff
RECOVER BEGIN
do recovery (you have access to what the code was, obviously)
IF not fully handled THEN
ESCAPE(whatever)
END;

If ESCAPE was called when you were not in a TRY RECOVER block it acted
like the C abort call.

Even a more limited form of this where you could only use "escape"
within a "try recover" block (just like you can only use continue within
a loop) would help a lot IMHO especially as I know some people don't
like the idea of an exception automatically propagating up several
layers before it is caught.
--
Flash Gordon
Living in interesting times.
Although my email address says spam, it is real and I read it.
 
Reply With Quote
 
__frank__
Guest
Posts: n/a
 
      10-28-2005
What do you think about following DAQmxErrChk ?
Parameter of DAQmxErrChk is the return code (status)
of function:


int32 DAQmxErrChk (int32 status)

char errBuff[2048];

{
if (status < 0)

{
DAQmxGetExtendedErrorInfo(errBuff,204;
printf("DAQmx Error: %s\n",errBuff);
exit(1)
}

}
 
Reply With Quote
 
__frank__
Guest
Posts: n/a
 
      10-28-2005
Got a warning, but it seems work:

warning C4715: 'not all control paths return a value
 
Reply With Quote
 
Flash Gordon
Guest
Posts: n/a
 
      10-28-2005
__frank__ wrote:
> Got a warning, but it seems work:
>
> warning C4715: 'not all control paths return a value


Haven't you seen the posts to this very group over the past two days
about the need to provide context? Since Thunderbird provides you the
context by default I'm not sure why you felt the need to delete it all
making your post illegible to anyone who happens not to have received
the article you are replying to.

As to the warning, it probably means exactly what it says. You have
written a function that is defined as returning a value but does not
under some conditions.
--
Flash Gordon
Living in interesting times.
Although my email address says spam, it is real and I read it.
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Read all of this to understand how it works. then check around on otherRead all of this to understand how it works. then check around on other thelisa martin Computer Support 2 08-18-2005 06:40 AM
Please help me understand this code.... randy Python 1 06-17-2005 09:13 PM
help understand source code in charpter 14.4 of accelerated C++ baumann@pan C++ 6 05-19-2005 08:46 AM
Tools to help to understand code written by another person Leny C Programming 4 01-11-2005 09:27 AM
Need help to understand this code error 'server error in /online application' Ketul Patel ASP .Net 1 11-29-2003 04:10 PM



Advertisments
 



1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57