Skip to article frontmatterSkip to article content
Site not loading correctly?

This may be due to an incorrect BASE_URL configuration. See the MyST Documentation for reference.

Comment documenter et quand faut-il commenter le code ?

IUT d'Orsay, Université Paris-Saclay

README

Licence

Example de la Licence MIT, une licence open-source très permissive :

Copyright <YEAR> <COPYRIGHT HOLDER>

Permission is hereby granted, free of charge, to any 
person obtaining a copy of this software and associated 
documentation files (the “Software”), to deal in the 
Software without restriction, including without 
limitation the rights to use, copy, modify, merge, 
publish, distribute, sublicense, and/or sell copies of 
the Software, and to permit persons to whom the Software 
is furnished to do so, subject to the following 
conditions:

The above copyright notice and this permission notice 
shall be included in all copies or substantial portions 
of the Software.

THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY 
KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO 
THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A 
PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, 
DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF 
CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 
IN THE SOFTWARE.

Documentation du code

Example de documentation en Doxygen (qui est très similaire à Javadoc) :

temperature.h
#ifndef TEMPERATURE_H
#define TEMPERATURE_H

/**
 * Represents a temperature in Celsius and Fahrenheit.
 *
 * This class allows you to store a temperature in Celsius, convert it to
 * Fahrenheit, and update it from either Celsius or Fahrenheit values.
 *
 * @par Example
 * @code{.cpp}
 * Temperature currentTemperature(25.0);
 *
 * currentTemperature.displayTemperature();
 *
 * // Output:
 * // Temperature: 25°C / 77°F
 * @endcode
 */
class Temperature {
private:
    double mCelsius;

    void validateCelsiusTemperature(double celsius) const;
    void validateFahrenheitTemperature(double fahrenheit) const;

public:
    /**
     * Constructs a new Temperature object.
     *
     * Initializes the temperature in Celsius.
     *
     * Absolute zero is −273.15°C.
     *
     * @param celsius The initial temperature in Celsius.
     *
     * @throws std::invalid_argument if celsius is below absolute zero.
     *
     * @par Example
     * @code{.cpp}
     * Temperature currentTemperature(25.0);
     *
     * // Temperature stored: 25°C
     * @endcode
     *
     * @par Invalid Example
     * @code{.cpp}
     * Temperature invalidTemperature(-300.0);
     *
     * // Throws std::invalid_argument
     * @endcode
     */
    Temperature(double celsius);

    /**
     * Gets the current temperature in Celsius.
     *
     * @return The temperature in Celsius.
     *
     * @par Example
     * @code{.cpp}
     * Temperature currentTemperature(25.0);
     *
     * double temperature = currentTemperature.getCelsius();
     *
     * // temperature == 25.0
     * @endcode
     */
    double getCelsius() const;

    /**
     * Sets the temperature in Celsius.
     *
     * This method directly updates the Celsius value.
     *
     * Absolute zero is −273.15°C.
     *
     * @param celsius The new temperature in Celsius.
     *
     * @throws std::invalid_argument if celsius is below absolute zero.
     *
     * @par Example
     * @code{.cpp}
     * Temperature currentTemperature(25.0);
     *
     * currentTemperature.setCelsius(10.0);
     *
     * // Temperature stored: 10°C
     * @endcode
     *
     * @par Invalid Example
     * @code{.cpp}
     * Temperature currentTemperature(25.0);
     *
     * currentTemperature.setCelsius(-300.0);
     *
     * // Throws std::invalid_argument
     * @endcode
     */
    void setCelsius(double celsius);

    /**
     * Gets the current temperature in Fahrenheit.
     *
     * @return The temperature in Fahrenheit.
     *
     * @par Example
     * @code{.cpp}
     * Temperature currentTemperature(25.0);
     *
     * double temperature = currentTemperature.getFahrenheit();
     *
     * // temperature == 77.0
     * @endcode
     */
    double getFahrenheit() const;

    /**
     * Sets the temperature using a value in Fahrenheit.
     *
     * Converts the Fahrenheit value to Celsius before storing it.
     *
     * Absolute zero is −459.67°F.
     *
     * @param fahrenheit The temperature in Fahrenheit.
     *
     * @throws std::invalid_argument if fahrenheit is below absolute zero.
     *
     * @par Example
     * @code{.cpp}
     * Temperature currentTemperature(25.0);
     *
     * currentTemperature.setFahrenheit(100.0);
     *
     * // Temperature stored: approximately 37.8°C
     * @endcode
     *
     * @par Invalid Example
     * @code{.cpp}
     * Temperature currentTemperature(25.0);
     *
     * currentTemperature.setFahrenheit(-500.0);
     *
     * // Throws std::invalid_argument
     * @endcode
     */
    void setFahrenheit(double fahrenheit);

    /**
     * Displays the temperature in both Celsius and Fahrenheit.
     *
     * This method prints the current temperature in both units.
     *
     * @par Example
     * @code{.cpp}
     * Temperature currentTemperature(25.0);
     *
     * currentTemperature.displayTemperature();
     *
     * // Output:
     * // Temperature: 25°C / 77°F
     * @endcode
     */
    void displayTemperature() const;
};

#endif

La syntaxe Doxygen/Javadoc :

/**
 * One sentence describing the class/method.
 *
 * More detailed descriptions here with one or multiple sentences.
 * 
 * @param parameterName Parameter description.
 * @return Output description if it exists.
 * @throws ExceptionThrown Exception description if it exists 
 * //@exception for older version of Java/Javadoc (< 17).
 */

Commenter

Choix d’implémentation

// Insertion sort is chosen for simplicity since the data set is small

Clarifications

double calculateLoanPayment(double principal, double annualRate, int months) {
    // Formula: P = (r*PV) / (1 - (1 + r)^(-n))
    // r = monthly interest rate, PV = present value (loan amount), n = number of payments
    double monthlyRate = annualRate / 12;
    return (monthlyRate * principal) / (1 - pow(1 + monthlyRate, -months));
}
// format matched hh:mm:ss MM dd, yyyy
regex timeMatcher("\\d*:\\d*:\\d* \\w* \\d*, \\d*");

De façon générale, il faut clarifier tout endroit où l’intention et/ou le contexte du code n’est pas clair.

Warning

// Dear maintainer:
// 
// Once you are done trying to 'optimize' this routine,
// and have realized what a terrible mistake that was,
// please increment the following counter as a warning
// to the next guy:
// 
// total_hours_wasted_here = 42
// the trim is real important. It removes the starting
// spaces that could cause the item to be recognized
// as another list. 
string listItemContent = trim(match.str(3));

TODO

// TODO : sorting procedure to be implemented

Mauvais commentaires

Beaucoup de commentaires sont une excuse pour du code de mauvaise qualité. Voici les erreurs à éviter.

Commentaires cryptiques

La racine carrée inverse rapide.

float Q_rsqrt( float number )
{
	long i;
	float x2, y;
	const float threehalfs = 1.5F;

	x2 = number * 0.5F;
	y = number;
	i = * ( long * ) &y; // evil floating point bit level hacking
	i = 0x5f3759df - ( i >> 1 ); // what the fuck?
	y = * ( float * ) &i;
	y = y * ( threehalfs - ( x2 * y * y ) ); // 1st iteration
//	y = y * ( threehalfs - ( x2 * y * y ) ); // 2nd iteration, this can be removed

	return y;
}

Une version améliorée avec la documentation dans le header :

/** 
 * Computes an approximation of 1 / sqrt(number) using the Fast Inverse Square Root method.
 *
 * This function is based on the original Quake III Arena algorithm.
 * It uses bit-level manipulation to obtain a rough approximation, followed by 
 * one iteration of Newton-Raphson refinement for improved accuracy.
 *
 * Explanation:
 * - https://en.wikipedia.org/wiki/Fast_inverse_square_root
 *
 * @param number The input floating-point number.
 * @return An approximation of 1 / sqrt(number).
 */

et le code suivant :

float fastInverseSquareRoot(float number) {
    static const uint32_t approximationConstant = 0x5F3759DF;
    static const float newtonRaphsonFactor = 1.5F;

    // Interpret the float as an integer for bitwise operations
    union {
        float approximation;  // Holds the estimated 1/sqrt(number)
        uint32_t bitwiseRepresentation; // Stores the bitwise equivalent of the float
    } inverseSqrtData = { .approximation = number };

    // Initial approximation using bitwise trick
    inverseSqrtData.bitwiseRepresentation = approximationConstant - (inverseSqrtData.bitwiseRepresentation >> 1);

    // One iteration of Newton-Raphson refinement
    // A second iteration can improve precision at the cost of time
    inverseSqrtData.approximation *= newtonRaphsonFactor - (0.5F * number * inverseSqrtData.approximation * inverseSqrtData.approximation);

    return inverseSqrtData.approximation;
}

Commentaires avec trop d’informations

/*
RFC 2045 - Multipurpose Internet Mail Extensions (MIME)
Part One: Format of Internet Message Bodies
section 6.8. Base64 Content-Transfer-Encoding
The encoding process represents 24-bit groups of input bits as output
strings of 4 encoded characters. Proceeding from left to right, a
24-bit input group is formed by concatenating 3 8-bit input groups.
These 24 bits are then treated as 4 concatenated 6-bit groups, each
of which is translated into a single digit in the base64 alphabet.
When encoding a bit stream via the base64 encoding, the bit stream
must be presumed to be ordered with the most-significant-bit first.
That is, the first bit in the stream will be the high-order bit in
the first 8-bit byte, and the eighth bit will be the low-order bit in
the first 8-bit byte, and so on.
*/

Commentaires redondants

Commentaires dans un code

Credits: Programmers Humor.

Commenter au lieu de coder proprement

bool isPasswordValid(const string& password) {
    // Pattern matches that:
    // - Must be between 8 and 20 digits
    // - Must contain at least one uppercase letter and one lowercase letter
    // - Must contain one number
    // - Must not include whitespace
    // - Must contain one of the following special characters: ! # $ % ^ & * 
    regex pattern("^(?=.*[A-Z])(?=.*[a-z])(?=.*[0-9])(?=.*[!#$%^&*])[\\S]{8,20}$");
    return regex_match(password, pattern);
}

Laisser du code commenté

InputStreamResponse response = new InputStreamResponse();
response.setBody(formatter.getResultStream(), formatter.getByteCount());
//InputStream resultsStream = formatter.getResultStream();
//StreamReader reader = new StreamReader(resultsStream);
//response.setContent(reader.read(formatter.getByteCount()));

Commenter au lieu de versionner

/*
11-Oct-2001 : Re-organised the class and moved it to new package com.jrefinery.date (DG);

05-Nov-2001 : Added a getDescription() method, and eliminated NotableDate class (DG);

05-Dec-2001 : Fixed bug in SpreadsheetDate class (DG);
*/