Skip to content

[Maintainability] clang-format is making code less readable #3450

@JimB123

Description

@JimB123

I'm a big fan of having some standard guidelines around code formatting. I'm also a fan of having automation check that these guidelines are being followed. But that's not what clang-format does.

clang-format reformats code based on a defined pattern. It's not just checking that a certain guideline is being followed. It decides exactly how the code should be formatted, and enforces that. In many cases, this is making the code less readable/maintainable.

From a quick search, it seems that most big open-source projects are using some type of lint tool to detect violations of guidelines. But most don't seem to use a formatter - and instead rely on code inspection for the final decision.

I was able to find an alternate tool AStyle which seems to focus on identifying poor patterns or styles deemed not acceptable rather than formatting into a specific fixed format. clang-format gives a choice: do it THIS way or do it THAT way, AStyle says this pattern is not allowed - but I won't mess with your other formatting.

Here are some examples of where clang-format is impacting readability: (Scroll right to see the corrections)

Original CodeFormatted Code
-typedef void   (*iteratorReleaseFunc)       (genericIterator *genIt);
-typedef fifo * (*iteratorGetEntriesFunc)    (genericIterator *genIt, int *orig_dbid, int *cur_dbid);
-typedef void   (*iteratorSwapDbFunc)        (genericIterator *genIt, int db1, int db2);
-typedef void   (*iteratorFlushDbFunc)       (genericIterator *genIt, int cur_dbid);
-typedef bool   (*iteratorHasPassedItemFunc) (genericIterator *genIt, const_sds key, int cur_dbid);
-typedef int    (*iteratorOriginalDbFunc)    (genericIterator *genIt, int cur_dbid);
-typedef bool   (*iteratorIsKeyInScopeFunc)  (genericIterator *genIt, const_sds key);
+typedef void (*iteratorReleaseFunc)(genericIterator *genIt);
+typedef fifo *(*iteratorGetEntriesFunc)(genericIterator *genIt, int *orig_dbid, int *cur_dbid);
+typedef void (*iteratorSwapDbFunc)(genericIterator *genIt, int db1, int db2);
+typedef void (*iteratorFlushDbFunc)(genericIterator *genIt, int cur_dbid);
+typedef bool (*iteratorHasPassedItemFunc)(genericIterator *genIt, const_sds key, int cur_dbid);
+typedef int (*iteratorOriginalDbFunc)(genericIterator *genIt, int cur_dbid);
+typedef bool (*iteratorIsKeyInScopeFunc)(genericIterator *genIt, const_sds key);
 struct genericIterator {
-    iteratorReleaseFunc         release;
-    iteratorGetEntriesFunc      getEntries;
-    iteratorSwapDbFunc          swapDb;
-    iteratorFlushDbFunc         flushDb;
-    iteratorHasPassedItemFunc   hasPassedItem;
-    iteratorOriginalDbFunc      originalDb;
-    iteratorIsKeyInScopeFunc    isKeyInScope;
 };
 struct genericIterator {
+    iteratorReleaseFunc release;
+    iteratorGetEntriesFunc getEntries;
+    iteratorSwapDbFunc swapDb;
+    iteratorFlushDbFunc flushDb;
+    iteratorHasPassedItemFunc hasPassedItem;
+    iteratorOriginalDbFunc originalDb;
+    iteratorIsKeyInScopeFunc isKeyInScope;
 };
-    return (!it->completed
-         && !it->terminated
-         && mutexQueueLength(it->items_for_iterator) < it->item_count_target);
+    return (!it->completed && !it->terminated && mutexQueueLength(it->items_for_iterator) < it->item_count_target);
-            serverAssert(it->dbentries_queued      >= it->dbentries_processed);
-            serverAssert(it->replication_queued    >= it->replication_processed);
-            serverAssert(it->swapdb_queued         >= it->swapdb_processed);
-            serverAssert(it->flushdb_queued        >= it->flushdb_processed);
+            serverAssert(it->dbentries_queued >= it->dbentries_processed);
+            serverAssert(it->replication_queued >= it->replication_processed);
+            serverAssert(it->swapdb_queued >= it->swapdb_processed);
+            serverAssert(it->flushdb_queued >= it->flushdb_processed);
 static bool expediteSingleKeyWithoutOptimization(
-        bgIterator *it,
-        int dbid,
-        robj *oKey,
-        dict *waitingOnKeys) {
-
     bool mustBlock = false;
 static bool expediteSingleKeyWithoutOptimization(
+    bgIterator *it,
+    int dbid,
+    robj *oKey,
+    dict *waitingOnKeys) {
     bool mustBlock = false;
-        if (!(iterComplete || it->keyset_iter->hasPassedItem(it->keyset_iter, key, dbid))
-                && (dictFind(it->early_iterate_entries, de) == NULL)) {
+        if (!(iterComplete || it->keyset_iter->hasPassedItem(it->keyset_iter, key, dbid)) && (dictFind(it->early_iterate_entries, de) == NULL)) {
-            if (!(iterComplete || it->keyset_iter->hasPassedItem(it->keyset_iter, key, dbid))
-                    && dictFind(it->early_iterate_entries, de) == NULL
-                    && ((bgIterationEntryMetadata *)objectGetMetadata(de))->iterator_epoch <= it->consistent_modification_id) {
+            if (!(iterComplete || it->keyset_iter->hasPassedItem(it->keyset_iter, key, dbid)) && dictFind(it->early_iterate_entries, de) == NULL && ((bgIterationEntryMetadata *)objectGetMetadata(de))->iterator_epoch <= it->consistent_modification_id) {
-    status->dbentries_queued      = it->dbentries_queued;
-    status->dbentries_processed   = it->dbentries_processed;
-    status->replication_queued    = it->replication_queued;
     status->replication_processed = it->replication_processed;
-    status->swapdb_queued         = it->swapdb_queued;
-    status->swapdb_processed      = it->swapdb_processed;
-    status->flushdb_queued        = it->flushdb_queued;
-    status->flushdb_processed     = it->flushdb_processed;
+    status->dbentries_queued = it->dbentries_queued;
+    status->dbentries_processed = it->dbentries_processed;
+    status->replication_queued = it->replication_queued;
     status->replication_processed = it->replication_processed;
+    status->swapdb_queued = it->swapdb_queued;
+    status->swapdb_processed = it->swapdb_processed;
+    status->flushdb_queued = it->flushdb_queued;
+    status->flushdb_processed = it->flushdb_processed;

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions