LabWindows/CVI

cancel
Showing results for 
Search instead for 
Did you mean: 

Cleaning up code - .h vs .c

A quick search of the forum indicates that folks use .h files only for defines (variables / functions), and then use .c files for the actual function code.  Right?

I have noticed that any errors occuring in functions in .h files are not captured by the LabWindows debugger (a random line in the main .c file is highlighted, and that line bears no resemblance to the error, making debugging much harder).  Are they captured correctly if the functional error occurs in a .c file?

Cheers.
__________________________________________
The world is full of exciting challenges,
brilliantly disguised as insoluble problems.
0 Kudos
Message 1 of 14
(4,593 Views)
As far as I understand:
- .h files are not compiled directly. They are just copied at the top of the .c file including the header. During  compilation, you compile the .c. If the error is in the header, you will not see it directly. The compiler will stop at the first "problem" in the .c. That's THE reason to limit the header file to very basic things.
- in debug mode, the error is usually at the function call level. That can be far away from the "real" problem... making the debug a hard job.
Cheers
0 Kudos
Message 2 of 14
(4,583 Views)
Hi Pythonist:

.h files are used to declare the public interface of a module in C.  This can include functions, variables, and macros.  .c files are used to implement the module (public and private functions, variables, and macros).  Using a .h file for the public interface keeps you from having to type the declaration over again in any modules that may call a particular function.  It also provides a single place to maintain the declarations.  This is how C implements information hiding.  Private functions should be declared in the .c file that implements them.  They should also be declared static to prevent others from poking around and using them anyway.

There is a page at WikiPedia about header files.

----
I am the founder of CnCSoftwareSolutions. When not cleaning up baby drool, I write about test data or work on Vision, a tool for understanding your test data. Visit me at www.cncsoftwaresolutions.com
0 Kudos
Message 3 of 14
(4,573 Views)
Right - hang on, though...

If I organise all like-minded functions into a single .h file (e.g. "foo.h" contain "bar" functions) to clean up the code in the main.c file, and put an #include "foo.h", I can then create another .h file ("foo2.h" with other "bar2" functions), I can call a "bar" within a "bar2" function.  This appears not to work if the .h files are .c files.

(I think I'm probably missing a more fundamental point about includes here...)
__________________________________________
The world is full of exciting challenges,
brilliantly disguised as insoluble problems.
0 Kudos
Message 4 of 14
(4,570 Views)
The .h files should contain declarations of the functions (ie the function prototypes), NOT the definitions of the functions (ie the function bodies). As a general rule only the .c files should actually cause any code to be generated, although it is possible (but severely frowned upon) to generate code in .h files. Perhaps this helps in your understanding?
 
JR
0 Kudos
Message 5 of 14
(4,568 Views)
Yep.  Tha's it.   Instead of the just the declarations, I have the full function code in the .h files - and interestingly, this does seem to work (although debugging is annoying, as stated).

Right, I'll go away and read up on how to do function declarations in .h files.  Just to stop me from further confusion, does the .h file include an "#include" for the .c file of the same name (containing the definitions of the declared functions), or is that assumed?

__________________________________________
The world is full of exciting challenges,
brilliantly disguised as insoluble problems.
0 Kudos
Message 6 of 14
(4,556 Views)
Hmmm.....  I guess I take this part of C programming for granted because I find it hard to explain....

Let's look at the function foo.  foo is a public function meant to be called by something in main.c.  We have decided that foo really needs to be it's own separate module because it completely handles the concept of doing foo.  foo is declared in foo.h and implemented in foo.c

foo.h:
int foo( int bar );

foo.c:
#include "foo.h"

static int foohelper( void );

int foo( int bar )
{
    return( foohelper() * bar );
}

static int foohelper( void )
{
    return( 2 );
}


As you can see the declaration of foo is in the header file.  The definition of foo is in the .c file.  The private function foohelper is declared at the top of the .c file and declared later in the .c file.  Because foohelper is not part of the public interface, it is not declared in the .h file. 

----
I am the founder of CnCSoftwareSolutions. When not cleaning up baby drool, I write about test data or work on Vision, a tool for understanding your test data. Visit me at www.cncsoftwaresolutions.com
0 Kudos
Message 7 of 14
(4,549 Views)

As far as the compiler is concerned, it will merge all the .h and .c files as directed by the #include statements into one mass of text and compile the lot in one go, which is why your code is working.

.h files commonly #include other .h files, but never .c files. CVI knows what .c files to compile from the definitions in the project window. Multiple .c files of a project (if you have more than 1) are all compiled individually (each with their own customised #include statements) and the resulting object files are all combined into a single executable. Sometimes it is necessary to prevent circular #include operations, where file1.h #includes file2.h which in turn #includes file1.h but we'll leave that for another time...

JR

0 Kudos
Message 8 of 14
(4,543 Views)
For your example, daijoubu, would you include the header in the main.c, or would simply having foo.c in the project automatically create the reference?  Basically, I'm still slightly fuzzy about how foo.c would know about functions described in foo2.c...

Cheers guys.

__________________________________________
The world is full of exciting challenges,
brilliantly disguised as insoluble problems.
0 Kudos
Message 9 of 14
(4,530 Views)
If foo.c needed to call functions defined in foo2.c and declared in foo2.h, then you would add an include statement for foo2.h.  Your new foo.c would look like:

#include "foo2.h"
#include "foo.h"

static int foohelper( void );

int foo( int bar )
{
    return( foohelper() * bar );
}

static int foohelper( void )
{
    return( 2 );
}

The same is true for main.c.  It's just another .c file.  Put the include that it needs at the top of the file.

Be careful about the order.  The order of include files is sometimes important.  Type definitions and macros in one header file can be used in another header file. 

By the way, there is nothing magic about the filename for the header files.  You could just as easily have named the include file for foo.c as bar.h instead of foo.h.  It's just good practice for them to use the same prefix unless you have a really good reason not to.  Someone else will one day have to figure out how your files are structured. 

Message Edited by daijoubu on 02-02-2006 04:11 PM

----
I am the founder of CnCSoftwareSolutions. When not cleaning up baby drool, I write about test data or work on Vision, a tool for understanding your test data. Visit me at www.cncsoftwaresolutions.com
0 Kudos
Message 10 of 14
(4,525 Views)