LinuxQuestions.org
Share your knowledge at the LQ Wiki.
Home Forums Tutorials Articles Register
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices


Reply
  Search this Thread
Old 12-15-2018, 02:50 PM   #1
Andy Alt
Member
 
Registered: Jun 2004
Location: Minnesota, USA
Distribution: Slackware64-stable, Manjaro, Debian64 stable
Posts: 528

Rep: Reputation: 167Reputation: 167
Question Dealing with static functions when building a program as a library


To implement unit testing, I've added a rule to build my program as a static library when "make check" is run. I wrap main() with #ifndef TEST_LIB and #endif (TEST_LIB is defined when it's built as a library).

Then I created some small C files to test some functions from that library.

Some of the functions from the library are declared statically.

Which you may guess produces warnings such as this when I try to compile the tests:

Code:
/../test/config_test.c:15:3: warning: implicit declaration of function ‘realize_home’ [-Wimplicit-function-declaration]
Because realize_home is declared statically in the source code (a .c file) for the program.

One solution I tried was to #include config_rmw (which contains the static functions) into the .c unit file (config_test). That actually works and doesn't give me any warnings when I compile, even though config_rmw.c is already built into the library.

Another solution I thought of was something like

Code:
#ifndef TEST_LIB
static
#endif
void function()
{
  definition
}
And adding the prototype to the header, which an #ifdef statement.

Code:
#ifdef TEST_LIB
function prototype
#endif
But doing that doesn't feel quite right, especially when it would have to be done for more functions as I proceed with implementing more unit tests.

I read in a book recently that static functions should go into a header file. I tried that but it only partially solved my problem. I wound up with compiler warnings like:

Code:
In file included from ../../src/rmw.c:38:0:
../../src/config_rmw.h:86:1: warning: ‘realize_home’ defined but not used [-Wunused-function]
 realize_home (char **str)
 ^~~~~~~~~~~~
I did some reading and I kind of understand why that happens. And basically that means I'd get a separate copy of that function in each .c file that #includes the header file where it's defined. Which I don't need. The reason I declare some functions statically is because they're only needed in one file.


Then I read some comments where people said static functions should never be defined in header files!

So... I'm stuck with wondering about the best approach and other options. I prefer to keep my programs organized and practice good coding skills.

I wrote some tests using just a script-based approach, which doesn't require my program to be built as a library, but I think there would be advantages to using both methods, depending on the functions that are being tested.

Last edited by Andy Alt; 12-16-2018 at 02:08 PM.
 
Old 12-17-2018, 02:25 AM   #2
NevemTeve
Senior Member
 
Registered: Oct 2011
Location: Budapest
Distribution: Debian/GNU/Linux, AIX
Posts: 4,871
Blog Entries: 1

Rep: Reputation: 1871Reputation: 1871Reputation: 1871Reputation: 1871Reputation: 1871Reputation: 1871Reputation: 1871Reputation: 1871Reputation: 1871Reputation: 1871Reputation: 1871
Try something like this:
Code:
/* foobar_test.c */

#include "foobar.c"

int main (void)
{
    do tests here
}
 
Old 12-17-2018, 05:02 AM   #3
pan64
LQ Addict
 
Registered: Mar 2012
Location: Hungary
Distribution: debian/ubuntu/suse ...
Posts: 21,930

Rep: Reputation: 7321Reputation: 7321Reputation: 7321Reputation: 7321Reputation: 7321Reputation: 7321Reputation: 7321Reputation: 7321Reputation: 7321Reputation: 7321Reputation: 7321
Quote:
Originally Posted by Andy Alt View Post
Code:
/../test/config_test.c:15:3: warning: implicit declaration of function ‘realize_home’ [-Wimplicit-function-declaration]
Because realize_home is declared statically in the source code (a .c file) for the program.
No, that is not the reason. implicit function declaration means the compiler found a call to that function before the declaration itself.

https://stackoverflow.com/questions/...ternal-linkage

Last edited by pan64; 12-17-2018 at 05:16 AM.
 
Old 12-17-2018, 11:56 AM   #4
Andy Alt
Member
 
Registered: Jun 2004
Location: Minnesota, USA
Distribution: Slackware64-stable, Manjaro, Debian64 stable
Posts: 528

Original Poster
Rep: Reputation: 167Reputation: 167
Quote:
Originally Posted by pan64 View Post
No, that is not the reason. implicit function declaration means the compiler found a call to that function before the declaration itself.

https://stackoverflow.com/questions/...ternal-linkage
That's the usual reason, but in this case the warning is being caused by the static declaration. I'm calling the function from config_test.c but it's defined statically in config_rmw.c. That warning never shows when I build the program for non-testing.


Quote:
Originally Posted by NevemTeve View Post
Try something like this:
Code:
/* foobar_test.c */

#include "foobar.c"

int main (void)
{
    do tests here
}
That's the method I've been using the last few days. And maybe I should just be happy with that since it's just set up that way for tests. I've been trained not to include .c files in other .c files so I wanted to investigate other options.

Last edited by Andy Alt; 12-17-2018 at 11:57 AM.
 
Old 12-17-2018, 12:16 PM   #5
pan64
LQ Addict
 
Registered: Mar 2012
Location: Hungary
Distribution: debian/ubuntu/suse ...
Posts: 21,930

Rep: Reputation: 7321Reputation: 7321Reputation: 7321Reputation: 7321Reputation: 7321Reputation: 7321Reputation: 7321Reputation: 7321Reputation: 7321Reputation: 7321Reputation: 7321
what you wish is (at least I think) against the rule of the language. static means it is local to that c file, so cannot be reached from outside.
you may try to add test functions:
Code:
static void realize_home(char **)
{
    implementation
}
#ifdef UNITTEST
void test_realize_home(char **v)
{
    realize_home(v);
}
#endif
 
1 members found this post helpful.
Old 12-17-2018, 12:25 PM   #6
NevemTeve
Senior Member
 
Registered: Oct 2011
Location: Budapest
Distribution: Debian/GNU/Linux, AIX
Posts: 4,871
Blog Entries: 1

Rep: Reputation: 1871Reputation: 1871Reputation: 1871Reputation: 1871Reputation: 1871Reputation: 1871Reputation: 1871Reputation: 1871Reputation: 1871Reputation: 1871Reputation: 1871
> I've been trained not to include .c files in other .c files so I wanted to investigate other options.

Yes, but that rule is for normal usages. This case is a special usage.
 
1 members found this post helpful.
  


Reply

Tags
c programming, libraries, static functions, unit testing



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 Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
How to add a static library to my own static library gmsa Programming 6 03-31-2010 08:33 AM
creating static library that includes another static library kskkumar Programming 2 10-22-2007 10:51 AM
Making a static library from a given shared library vro Programming 1 07-27-2007 04:07 PM
LINUX - linking archive (static library) with shared (dynamic) library gurkama Programming 5 03-04-2007 11:11 PM
howto compile bin with my library using all-static and shared linked standart library stpg Programming 4 06-29-2004 04:20 AM

LinuxQuestions.org > Forums > Non-*NIX Forums > Programming

All times are GMT -5. The time now is 11:54 PM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Open Source Consulting | Domain Registration