Is it completely unheard of to have a .c file dedicated to just data? In my case, I'd be using it for global variables that are shared across two other .c files. Here's specifically how I'm using it.

// serverth.h

struct serverth_parameters {
    struct { // right now, this is the only struct needed
        char * root,
             * user,
             * public,
             * site;
    } paths;

    // I anticipate needing another struct here


extern struct serverth_parameters parameters;

// serverth.c

#include "serverth.h"

struct serverth_parameters parameters = {
    .paths = { // macros are actually used here

parameters is a struct that's used for a websockets server, in two files:

  • One for HTTP (uses parameters.paths.site)
  • Two for proprietary protocols (both use .paths.user, one uses paths.public)

Is this a bad practice? Do people do this? Or, is it more conventional to just keep the data in the source file in which it is most relevant?

  • It's not unheard of, but I'm scared that you feel like you need such a file and that you'd think you need to put more globals in there. – haylem Jun 12 '13 at 20:51
  • okay, I'll explain the context a little more – tay10r Jun 12 '13 at 20:52
  • sounds acceptable, as long as these "global variables" you originally mentioned can be defined as constants as we see them here. – haylem Jun 12 '13 at 21:39
  • 1
    okay, I've already taken it out. I'm not sure how I started thinking that in the first place – tay10r Jun 13 '13 at 8:12
  • 1
    Pre-computed tables/matrices/encodings may serve as reasonable candidates for data as source files. Device IO maps are another take on that same idea. – JustinC Jun 20 '13 at 7:33

In general I'd be wary of "dumping ground" files, where one would start listing global variables or long lists of #defines.

However, if by "globals" you actually meant that these globals would be constants, then that would seem acceptable, as long as they are structured and re-grouped in meaningful patterns, and that the extent of their reuse justifies to extract them to a separate file.

If these conditions aren't satisfied, then I'd usually restrain them to the file where they're expected to be used, if possible.

Include Guards

On a different note, I don't know how your files are compiled and what build system you use, but you might want to use compilation guards of the form:

#ifndef MY_MODULE
# define MY_MODULE

/* stuff here */

  • I'm using cmake. you're talking about the header file right? – tay10r Jun 12 '13 at 22:31
  • @TaylorFlores: yes, sorry if that was confusing. – haylem Jun 12 '13 at 22:31
  • 1
    Include guards should not start with underscores (and once you get rid of those, the trailing underscores look silly). Names starting with double underscores, or a single underscore and a capital letter, are reserved for the implementation. Just use #ifndef MY_MODULE or MY_MODULE_H – user7043 Jun 13 '13 at 0:20
  • @delnan: guards should not start with underscores that's just, lile, you know, your preference (and convention), man :) It's not the most adopted convention, but who cares. Works all the same. I agree on the missing _H though, I had forgotten that, but usually I used names with it indeed. – haylem Jun 13 '13 at 0:39
  • 1
    @delnan: I just checked the standard and you are right. I thought only the C++ standard mandated that, but the ISO/IEC 9899 mandes it as well. I stand corrected. Thanks. – haylem Jun 13 '13 at 8:12

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.