Discipline Matters: Refactoring of Preprocessor Directives in the #ifdef Hell

Flávio Medeiros, Márcio Ribeiro, Bruno Ferreira, Rohit Gheyi, Sven Apen, Christian Kästner, and Baldoino Fonseca

Overview

The preprocessor is used in almost all C projects to support variability and portability. However, many researchers and practitioners criticize the C preprocessor because of its negative effect on code understanding and maintainability, and its error proneness. More importantly, the use of the preprocessor hinders the development of tool support that is available in other languages, such as automated refactoring. Developers aggravate these problems when using the preprocessor in undisciplined ways (e.g., conditional blocks that do not align with the syntactic structure of the code). To address these problems, we proposed a catalog of refactorings to resolve undisciplined preprocessor usage in a previous study, and we offered an Eclipse plug-in that automatizes our refactorings. In this article, we evaluated our catalog regarding the number of application possibilities in practice, opinion of developers, and behavior preservation. Overall, we found 5670 application possibilities for our refactorings in 63 real-world projects. We performed an online survey among 202 developers, and we submitted 28 patches to convert undisciplined into disciplined directives. According to our results, most developers prefer to use the refactored (i.e., disciplined) version of the code instead of the original code with undisciplined preprocessor usage. To verify that our refactorings are indeed behavior preserving, we applied them to more than 36 thousand programs generated automatically using a model of a subset of the C language, and run the same test cases in the original and refactored programs. Furthermore, we applied the refactorings in three real-world projects: BusyBox, OpenSSL, and SQLite. This way, we detected and fixed a few behavioral changes introduced by our refactorings, the majority caused by unspecified behavior in the C language.


Number of Application Possibilities for our Refactorings

We investigate whether the undisciplined directives considered by our refactorings appear in real-world C projects. Our goal is to show that there are several possibilities to apply our refactorings in many real-world projects. To this end, we perform a large-scale study to learn whether developers can apply our refactorings in several places and in different projects. Please download the results here.


Model of the C Language

We create a model of a subset of the C language in Alloy to generate configurable programs with an opportunity to apply our refactorings. Download the complete C model in Alloy.


Patches Submitted to the Projects

To further understand the real-world relevance of our refactorings (RQ2), we submitted 28 patches to popular C projects. We want to know whether undisciplined directives are important enough to motivate developers to change code only to remove these directives. For selecting projects, we used SHTorrent,5 identifying active projects that heavily use pull requests on GitHub. We submitted patches to the 28 most active projects with application possibilities for our refactorings. Overall, developers accepted 21 (75%) patches, one each in: Angband; Amxmodx; Asfmapready; Collectd; Curl; Dmd; Libpng; Linux; Mapserver; Machinekit; Mongo; Opensc; Openssl; Opentx; Ossec-hids; Retroarch; Sleuthkit; Syslog-ng; Taulabs; Uwsgi; and Wiredtiger.

Table I: Patches.

      Project       Status       Link      
angband accepted details
amxmodx     accepted     details
      asf_mapready           accepted     details
curl accepted details
dmd     accepted with minor changes     details
libpng     accepted with minor changes     details
linux kernel accepted with minor changes details
mapserver     accepted     details
machinekit accepted with minor changes details
mongo-c-driver accepted details
opensc     accepted     details
openssl accepted with minor changes details
opentx     accepted with minor changes     details
ossec-hids accepted details
retroarch     accepted with minor changes     details
sleuthkit     accepted     details
syslog-ng accepted with minor changes details
uwsgi     accepted with minor changes     details
collectd     Accepted     details
taulabs     accepted     details
wiredtiger     accepted     details
ethersex     rejected     details
freeradius     rejected     details
hexchat rejected details
kerberos     rejected     details
irssi     rejected     details
openvpn     rejected     details
pacemaker     rejected     details

Contact

This work was developed at the Federal University of Campina Grande (UFCG), Brazil. If you have any question, please contact the researcher:

Flávio Medeiros
Email: flaviomotamedeiros at gmail.com.
SPG - Software Productivity Group