473,491 Members | 2,221 Online
Bytes | Software Development & Data Engineering Community
Create Post

Home Posts Topics Members FAQ

Pse, help me to understand this code

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,2048);
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;
}
Nov 15 '05 #1
18 4582
__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,2048);
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.
Nov 15 '05 #2
Flash Gordon <sp**@flash-gordon.me.uk> 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
Nov 15 '05 #3
On 2005-10-28, __frank__ <no***********@indirizzo.non.valido> 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?
Nov 15 '05 #4
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).
Nov 15 '05 #5
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
Nov 15 '05 #6
Richard Bos wrote:
Flash Gordon <sp**@flash-gordon.me.uk> 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.
Nov 15 '05 #7
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,2048);
printf("DAQmx Error: %s\n",errBuff);
exit(1)
}

}
Nov 15 '05 #8
Got a warning, but it seems work:

warning C4715: 'not all control paths return a value
Nov 15 '05 #9
__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.
Nov 15 '05 #10
__frank__ wrote:
What do you think about following DAQmxErrChk ?
In reference to what? Leave in some context when replying so people can
see what you are talking about.
Parameter of DAQmxErrChk is the return code (status)
of function:

int32 DAQmxErrChk (int32 status)

char errBuff[2048];

{


Even given a definition of int32 I think that this is not valid C. Local
variables should be declared after the opening brace not before it.I did
not read further.

<snip>
--
Flash Gordon
Living in interesting times.
Although my email address says spam, it is real and I read it.
Nov 15 '05 #11
Flash Gordon <sp**@flash-gordon.me.uk> wrote:
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.


It's probably not this, but I would think there is a possibility that
a crappy compiler might issue such a warning for the following code,
which is similar to OP's:

int myfunc( void ) {
if( /*...*/ ) {
exit( 0 );
}
else {
return 0;
}
}

If it isn't smart enough to recognize that the call to exit()
constitutes a "return" of sorts, it might complain as OP's compiler
did.

--
Christopher Benson-Manica | I *should* know what I'm talking about - if I
ataru(at)cyberspace.org | don't, I need to know. Flames welcome.
Nov 15 '05 #12
Flash Gordon ha scritto:
Even given a definition of int32 I think that this is not valid C. Local
variables should be declared after the opening brace not before it.


Ok. Please, let me know what do you think about the following code.
Compiling I got no errors, no warnings:

/************************************************** ***/
int DAQmxErrChk (int32 status)
{

char errBuff[2048]={'\0'};

if (status < 0)
{

DAQmxGetExtendedErrorInfo(errBuff,2048);
printf("DAQmx Error: %s\n",errBuff);
return 1;
}

else
return 0; /* No error */

}
Nov 15 '05 #13
__frank__ wrote:

<snip>
Ok. Please, let me know what do you think about the following code.
Compiling I got no errors, no warnings:

/************************************************** ***/
int DAQmxErrChk (int32 status)
Why don't you just use int? Do status codes *really* require 32 bits
(which is what I assume int32 is)?
{

char errBuff[2048]={'\0'};
Did you realise that this would initialise *all* 2048 bytes of errBuff?
This is probably a waste, although it won't stop the function from working.
if (status < 0)
{

DAQmxGetExtendedErrorInfo(errBuff,2048);
Since, I presume, the above function always writes a string to the
provided buffer I would be surprised if errBuff actually needed any
initialisation.
printf("DAQmx Error: %s\n",errBuff);
It is generally useful to send error messages to stderr (the standard
error stream) instead of stdout.
fprintf(stderr,"DAQmx Error: %s\n",errBuff);
return 1;
}

else
return 0; /* No error */

}


The function should work as far as I can see, assuming sensible
definitions of int32, DAQmxGetExtendedErrorInfo and inclusion of stdio.h
--
Flash Gordon
Living in interesting times.
Although my email address says spam, it is real and I read it.
Nov 15 '05 #14
Flash Gordon ha scritto:
Why don't you just use int? Do status codes *really* require 32 bits
(which is what I assume int32 is)?
The variuos DAQmx are defined to return a "int32" (typedef of long in
NIDAQmx.h) so I would to use these typedef.

fprintf(stderr,"DAQmx Error: %s\n",errBuff);
Right, it's better.

The function should work as far as I can see


So far so good. Hope to make a little improved source.

Thanks again
Nov 15 '05 #15
Flash Gordon ha scritto:
Why don't you just use int? Do status codes *really* require 32 bits
(which is what I assume int32 is)?


Here you are examples of status codes (printed by mean of
DAQmxGetExtendedErrorInfo):
Task Name: voltage1

Status Code: -200220
DAQmx Error: Specified operation cannot be performed when there are no
channels
in the task.
Task Name: voltage1

Status Code: -200478
DAQmx Error: Specified operation cannot be performed when there are no
channels
in the task.
Task Name: voltage1

Status Code: -200478
Nov 15 '05 #16
Jordan Abel <jm****@purdue.edu> writes:
On 2005-10-28, __frank__ <no***********@indirizzo.non.valido> 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?


Actually, that's not correct. Of the three lines, the first is a
valid comment. The leading "/*" on the second line introduces a
second comment, which is terminated by the trailing "*/" on the third
line.

It's confusing because there's a "*/" on the second line that doesn't
close a comment (because the '*' is part of the "/*" that introduces
it), and a "/*" on the third line that doesn't introduce a comment
(because it's already within a comment, and comments don't nest).

It's horrible style, requiring too much effort by the reader to
confirm that it's valid, but it's not actually wrong.

Either of the following would be better:

/*
* DAQmx Configure Code
*/

or

/*********************************************/
/* DAQmx Configure Code */
/*********************************************/

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
Nov 15 '05 #17
On 2005-10-30, Keith Thompson <ks***@mib.org> wrote:
Jordan Abel <jm****@purdue.edu> writes:
On 2005-10-28, __frank__ <no***********@indirizzo.non.valido> 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?


Actually, that's not correct. Of the three lines, the first is a
valid comment. The leading "/*" on the second line introduces a
second comment, which is terminated by the trailing "*/" on the third
line.

It's confusing because there's a "*/" on the second line that doesn't
close a comment (because the '*' is part of the "/*" that introduces
it), and a "/*" on the third line that doesn't introduce a comment
(because it's already within a comment, and comments don't nest).


That's what i was trying to say - _this_ happens to be a valid
comment (well, two comments) but if he tried to do

/******/ /*/ 1 /*/ 2 /*/ 3 /*/ 4 /******/
it would become
/*....*/ /*.....*/ 2 /*.....*/ 4 /*....*/

and
/******/ /*/ 1 /*/ 2 /*/ 3 /******/
becomes
/*....*/ /*.....*/ 2 /*..........*/
It's horrible style, requiring too much effort by the reader to
confirm that it's valid, but it's not actually wrong.

Nov 15 '05 #18
On 2005-10-30, Keith Thompson <ks***@mib.org> wrote:
Jordan Abel <jm****@purdue.edu> writes:
On 2005-10-28, __frank__ <no***********@indirizzo.non.valido> wrote:
/*********************************************/
/*/ DAQmx Configure Code
/*********************************************/


Actually, that's not correct. Of the three lines, the first is a
valid comment. The leading "/*" on the second line introduces a
second comment, which is terminated by the trailing "*/" on the third
line.

It's confusing because there's a "*/" on the second line that doesn't
close a comment (because the '*' is part of the "/*" that introduces
it), and a "/*" on the third line that doesn't introduce a comment
(because it's already within a comment, and comments don't nest).

It's horrible style, requiring too much effort by the reader to
confirm that it's valid, but it's not actually wrong.

Either of the following would be better:

/*
* DAQmx Configure Code
*/

or

/*********************************************/
/* DAQmx Configure Code */
/*********************************************/


Or the fantabulous:

/************************************************** *******/
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/* DAQmx Configure Code!!! * * * * * * * * * * * * * * * */
/* * * * DAQmx Configure Code!!! * * * * * * * * * * * * */
/* * * * * * * * DAQmx Configure Code!!! * * * * * * * * */
/* * * * * * * * * * * * DAQmx Configure Code!!! * * * * */
/* * * * * * * * * * * * * ** * *DAQmx Configure Code!!! */
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/************************************************** *******/

But seriously, comment decorations are a waste. They add very
little and are a pain to maintain.

/* DAQmx Configure Code */

--
Neil Cerutti
Nov 15 '05 #19

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

Similar topics

11
3576
by: BoonHead, The Lost Philosopher | last post by:
I think the .NET framework is great! It's nice, clean and logical; in contradiction to the old Microsoft. It only saddens me that the new Microsoft still doesn't under stand there own...
10
2236
by: forgotten field | last post by:
Hi,how are you? I have been studying C++ by myself, but recently I am having a real problem. I am learning about the basic usage of a doubly linked list using polymorphism. However, I have got the...
10
1752
by: Simon Mansfield | last post by:
I have been given a list of exercises to do by my tutor, one of which is this: http://www.cems.uwe.ac.uk/~amclymer/Software%20Design%20and%20C++/Exercises/Exercise%208/Exercise.html Which i am...
9
4972
by: TCMA | last post by:
I am looking for some tools to help me understand source code of a program written in C++ by someone else. Are there any non-commercial, open source C or C++ tools to reverse engineer C or C++...
13
2938
by: Terry Andersen | last post by:
Could anyone please help me understand what is going on in the code below. A short explanation would be nice..... Best Regards Terry struct mystruct { unsigned char testchar; unsigned short...
51
2495
by: Richard Hengeveld | last post by:
Hi all, I'm trying to understand how pointers for function parameters work. As I understand it, if you got a function like: void f(int *i) { *i = 0; }
2
16634
by: DC | last post by:
Hi, I need to asynchronously read from a network (TCP) stream, and I am having trouble with retrieving whole blocks; I get a break in the data block every 1460 bytes which relates to network...
54
3337
by: smnoff | last post by:
Below is a section from string.c at this linkhttp://cvs.opensolaris.org/source/xref/on/usr/src/common/util/string.cthat I am trying to fully understand.I don't fully understand LINE 514; not to...
2
1910
by: Carnell, James E | last post by:
I am thinking about purchasing a book, but wanted to make sure I could get through the code that implements what the book is about (Artificial Intelligence a Modern Approach). Anyway, I'm not a...
3
1539
by: Ben Thomas | last post by:
Hello, I have the following code which I don't understand why it works : #include <iostream> using namespace std; void DontWork (unsigned int& i) { cout << i << endl; }
0
7115
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
6978
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
7154
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,...
0
7190
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...
1
4881
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new...
0
3076
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
0
1392
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 ...
1
633
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.
0
280
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...

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.