0

I have a complex C structure DATABSECONTEXT. Developers keep adding different fields in this structure. We review and then accept. But sometimes there is a lack of synchronization. There is a complex routine function1(), where we need to access different fields and work over them. So if any newly added field in the structure if not taken care in function1(), it will be left as NULL. Which is an inconsistent state, and will cause crashes later.

I want to achieve the following: Whenever some field is added in this DATABSECONTEXT structure, there should be some mechanism of forced alert/message to the developer, to re-visit the related function function1().

I thought of maintaining a header file, which will have a macro for each field we touch in function1(). Say for field dbCurrency used in function1() I can do

headerfile1.h

    #define dbCurrency_funciton1  

field definition macro inside the structure can be modified as:

headerfile2.h
    #define funname restruc
    #define PASTER(x,y) x ## _ ## y
    #define NAME(fun) PASTER(fun, funname)

    #define MY_ELEMENT(dtype, mname)  dtype mname;\
                                      #ifndef (NAME(mname)) \
                                      #error "please visit funciton1() and add macro @NAME(mname) in headerfile.h"
                                      #endif

    struct DATABSECONTEXT
    {
    MY_ELEMENT(char,   newlyAddedElement);
    };

but such use of preprocessor directives are not allowed in MACROS.

Went through following links (and many more)but could not find anything working for me. Link1, Link2

Any suggestions on how to achieve this in an elegant way?

Yogesh
  • 565
  • 3
  • 21
  • You could write a unit test checking whether or not the parts of that subroutine are still working as expected. – lilezek Nov 23 '17 at 12:11
  • 2
    You could use a [static assert](https://stackoverflow.com/questions/3385515/static-assert-in-c) on the size of the structure, either native or roll your own if you're using older compilers. – unwind Nov 23 '17 at 12:19
  • 1
    Rather than using macros (which a clumsy or determined developer might not use properly) write a program that inputs the source code of `function1()` and the header file, and checks that it sets value of all members of the data structure as specified in the header. If there are any members not being set, print an appropriate message and terminate with an error condition. Then set up the build script so it runs that program whenever the header file changes. [If need be have that program check preprocessed source]. – Peter Nov 23 '17 at 12:22
  • @lilezek Thanks but if a new field is added in this structure generally its a new feature and there is no affect on backward compatibility. But the crashes will come only when this new functionality is executed and function1 is invoked before that. function1 is a rarely invoked functionality. Also new field is known only to the developer, so precompiled unit test cannot help here. – Yogesh Nov 23 '17 at 12:42
  • @Peter This is the only option I can also think. Thanks for sharing your idea. – Yogesh Nov 23 '17 at 12:44
  • @unwind the size of the structure can vary on different platforms. That is another point of increasing code maintenance. I think It will need system dependent layer to kick in. – Yogesh Nov 23 '17 at 12:50
  • Make sure there are appropriate comments where the structure is defined, so that if anyone adds a field, they know where else they need to do work. If they're not competent enough to read such information and it isn't part of the team's 'folklore' (generally known information about how to maintain the software), then you have big problems with the team. – Jonathan Leffler Nov 23 '17 at 21:18
  • Thanks @JonathanLeffler, comments are already there, the team is really competent but to err is human, and to take care of that human err is automation ;). – Yogesh Nov 24 '17 at 04:41
  • Agreed, but there's an element of "code reviews help ensure that it takes two human failures", and while I laud the goal of trying to spot the problem automatically, 'tis hard at best. Maybe you can (automatically) generate a function using the specification of the structure to check that every field is properly set. Then just arrange to call that in appropriate places. But people shouldn't be adding a field without knowing all about where it will be used and where it must be set, etc.\ – Jonathan Leffler Nov 24 '17 at 04:59

1 Answers1

0

If you can check it in runtime, you can assert size of the struct against expected size. If anyone adds new field, the size will change, so you can raise an error informing that function1 and size must be updated.


edit: this solution doesn't guarantee coverage of certain cases described by guys below

jedzej
  • 422
  • 3
  • 12
  • There is no need to it at runtime. You can use `sizeof` with static assertions. – user694733 Nov 23 '17 at 12:42
  • 3
    Although adding new members will often change the size of a data structure, that is NOT guaranteed. Padding and alignment can interfere with that, particularly when new members are small (and fit into existing padding). – Peter Nov 23 '17 at 12:49
  • @Peter exactly, the size of the structure can vary on different platforms. That is another point of increasing code maintenance. It will need system dependent layer to kick in. – Yogesh Nov 23 '17 at 12:51