I deeply loath 'documentation' made using Doxygen because the output just lacks the one important thing: why is the code the way it is and what are the relations of functions?
Exactly, Doxygen is cancerous. The purpose is to let the programmers be lazy, and give the impression of having documentation to the higher-ups who just look at it and say "looks nice, 'have nice documentation' checkbox marked".
Just worked with Eclipse PAHO embedded mqtt client, and the Doxygen documentation is just... none:
/** MQTT Subscribe - send an MQTT subscribe packet and wait for suback before returning.
* @param client - the client object to use
* @param topicFilter - the topic filter to subscribe to
* @param message - the message to send
* @return success code
*/
DLLExport int MQTTSubscribe(MQTTClient* client, const char* topicFilter, enum QoS, messageHandler);
This is nearly useless, literally the only useful information not conveyed already by the names is "wait for suback before returning".
For example, crucial piece of information in any C library where pointers are passed to functions which modify the internal state of the library is, who is responsible of the lifetime (memory allocation) of the object? Many other similar looking functions internally do
memcpy on the pointer to some internal buffer, but this particular piece of crap just copies topicFilter pointer to be used later, so you can't generate the filter string in stack and just call the function, or everything breaks down in mysterious ways. Both are valid strategies but you have to tell the user which it is, and it would have been literally 15 seconds of typing to tell me that.
Further, you can see they copy-pasted the description from some other function, so not only the documentation is lacking, it's wrong, too. Bright side is, as this documentation is useless anyway, no one reads it so no one notices the mistake, and managers are happy about the nice-looking "API documentation".
We programmers - we just look at the code and figure out what is does, how it does it - and finally, try to guess
why. And when we can't figure out why PAHO, for example, checks if return codes are < 0 (errors) and then replace them with fixed -1 to hide the original error code and just tell the application about a generic error, we come into conclusion there is no sensible reason to do so, and fix the crap, removing those extra steps and make error codes propagate again.