Sign in to follow this  

Fancy C++ comments.

This topic is 2562 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

In my library I added very in depth comments to every single class, function, and variable in the headers. The comments are similar to MSDN code reference. For example:


// ===============================================================================
// Parameters:
//
// mesh
// [in] The mesh object that will be displayed for the actor.
//
// radius
// [in] The radius of the actor's capsule within the physics scene which is the distance at which a
// character comes in contact with objects in the character's vertical plane.
//
// height
// [in] The hieght of the actor's capsule within the physics scene which is the distance at which a
// character comes in contact with objects in the character's horizontal plane.
//
// matrix
// [in] The matrix which defines the the starting pose of the actor.
//
// Return Value:
// Returns a pointer to the actor.
//
// Remarks:
// This function adds a actor to the scene. Actors use a character controller class within the physics
// scene that offers a standard video game character interface.
// ===============================================================================
AxActor* CreateActor( AxMesh* mesh, float radius, float height, XMMATRIX* matirx );



When in Visual C++ you can see these comments in a popup box as you are browsing the variables and functions of a class. To me this is a pretty awesome way to use comments as an in source reference manual.

I notice that DirectX and many other professional APIs don't do this and this makes me wonder if it's a good idea. Is it a good or bad thing that I am doing this and why?

Share this post


Link to post
Share on other sites
Yea, it's pretty clean looking. I don't think anyone can tell you that it's good or bad. All that matters is that it helps you understand your code.

Just don't get all stuck spending massive time writing comments that no ones going to read ever.

Share this post


Link to post
Share on other sites
Are you wondering why there are not large sections of comments like this in directx? Large code comments like what you posted are fine for small projects, but when the amount of actual code becomes large, those comments make readability extremely difficult.

Share this post


Link to post
Share on other sites
Quote:
Original post by smasherprog
Are you wondering why there are not large sections of comments like this in directx? Large code comments like what you posted are fine for small projects, but when the amount of actual code becomes large, those comments make readability extremely difficult.

This.
If you have a 100% fixed interface on your shipped library. Then by all means, document in the code if you want. If you are working on an inproduction game, enjoy trying to maintain it.

In a header, while it may seem useful, it quickly makes the file hard to grok quickly, as it spaces out the code too much. (sure folding, intelesense, and whatnot help fix this but they aren't always available). A header file is your way to view an interface for something, and should be 100% as useful with out without your standard tools.

Secondly, code is mutable. While radius and height may be all your CreateActor needs now, maybe later on you will need to pass a "width" and a "color" and then you may consolidate it into a "struct ActorParams". Keeping all that documentation in sync on a fast changing code base is a nightmare. Prefer to have code that is self commenting. Infact, your sample is more readable without the comments. If you comment, you should be outlining purpose and gotchas, not the nitty gritty that is obvious.

Try this:

// CreateActor,
// Returns a new actor, or NULL if out of reserves. displayMesh may be NULL.
AxActor *CreateActor( AxMesh *displayMesh, float collisionRadius, float collisionHeight, XMMATRIX *spawnLocation );

Share this post


Link to post
Share on other sites
I'd say, avoid _documenting_ your code _inline_ (but do it properly external!), and only start commenting your code in the rare cases it is needed. For the reasons KulSeran gave.

Share this post


Link to post
Share on other sites
When I was learning openGL I just took a look on the header file and I knew (most of the times) what a function did. I would use more descriptive names, so the thing becomes self explaining.

Maybe it's just me, but I usually group parameters so that similar types/looking parameters are grouped. But always: output parameters first, input parameters last. But it's just personal preference.

So:
AxActor* CreateActor( AxMesh* display_mesh, XMMATRIX* pose_matirx, float physics_radius, float physics_height); 
// or maybe: float collision_radius, float collision_height



Okay, I've just woken up and the names are a bit clumsy, but I guess you get the idea:

description of the parameters: parameter names themselves
remarks: the function name itself
return value: it should be obvious by the return type, or the function name and return type

EDITED a bit

[Edited by - szecs on December 4, 2010 2:17:24 AM]

Share this post


Link to post
Share on other sites
Most of the comments I see on a daily basis are either incorrect, outdated, help very little because they lack any context or explanation and are more like quick "notes" for the original implementer, or don't provide any helpful information because they explain the obvious:

// Clearing the string, just in case you were't familiar with the standard library and shouldn't be working here in the first place
myStr.clear();


As such, I've tried to cut down on comments unless something is legitimately going to be difficult to understand, in which case I write a few sentences. Systems and architectures in general are documented in a separate Wiki.

Share this post


Link to post
Share on other sites
Never repeat yourself.


This especially means that you shouldn't be commenting information that can be obviously inferred from the code itself. By corollary, it means you should be choosing your code structure and namings carefully in order to maximize the amount of information conveyed via the code itself and totally eliminate the need for verbose external comments.

Share this post


Link to post
Share on other sites
Quote:
Original post by Zipster
Most of the comments I see on a daily basis are either incorrect, outdated, help very little because they lack any context or explanation and are more like quick "notes" for the original implementer, or don't provide any helpful information because they explain the obvious:

// Clearing the string, just in case you were't familiar with the standard library and shouldn't be working here in the first place
myStr.clear();


As such, I've tried to cut down on comments unless something is legitimately going to be difficult to understand, in which case I write a few sentences. Systems and architectures in general are documented in a separate Wiki.


Yes self explanatory comments like that is useless, it is much better to comment trickier part of the code.
Also having a description of each function, what it does and returns helps a lot for maintainability.

For example when I write code, almost 2/3 of the lines are function/class/module descriptions used to generate the API. Often my code is pretty simple so I do not put many comments in the code itself. However there are parts that has at least a few lines of comments in trickier parts of the function.

For example this would be a good comment:

if(vertexCount <= 0) {
// Easy memory leak here if we forget to delete mFaces before returning.
delete[] mFaces;
return;
}


And this would be a bad comment:

if(vertexCount <= 0) {
// Freeing up faces.
delete[] mFaces;
return;
}


For C/C++/PHP I used doxygen successfully, with Erlang edoc is the way to go.

Share this post


Link to post
Share on other sites
I actually like doxygen, and use doxygen formatted comments religiously. It does take a rather large amount of discipline to keep straight, so I do have a few practices I keep to.

Firstly, I'm also really disciplined about proper naming conventions and literate programming. This alone goes a long way to reducing the amount of documentation needed, and has the side effect that what documentation you do need can stay at a higher-level -- e.g. if it's clear which variables and parameters are vectors, you can speak generally of vectors, rather than being tempted to use variable names (this is part of the earlier advice of "don't repeat yourself").

That said, you want to keep on-topic. I use doxygen comments only for API reference documentation. Conceptual material, how-tos and examples longer than a line or two belong in external documentation, not inline documentation.

The last thing I do is that I refrain from documenting until I'm reasonable certain that a section of code is stable. This way you don't repeat too much work when things change. You also have to be vigilant to ensure comments remain up-to-date in the face of new features or bug-fixes, so consider the documentation as a bug whenever things change until you've reviewed its accuracy.

Share this post


Link to post
Share on other sites
Quote:
Original post by flodihn
For example this would be a good comment:

if(vertexCount <= 0) {
// Easy memory leak here if we forget to delete mFaces before returning.
delete[] mFaces;
return;
}


And this would be a bad comment:

if(vertexCount <= 0) {
// Freeing up faces.
delete[] mFaces;
return;
}


Both comments say exactly the same thing, in which I prefer the _second_ one, since it is much more compact and to the point. It is namely obvious that we leak if we don't delete and obvious that the action is done before returning.

I only ever comment when I view the code for the second time and don't get what is going on. This OFTEN is at spots where I've done optimization. Optimization obfuscates the code, so comment at spots where you optimize the code!

For the rest, beside that I don't use Doxygen, I totally agree with Ravyne.

Share this post


Link to post
Share on other sites
Quote:
Original post by Decrius
Quote:
Original post by flodihn
For example this would be a good comment:

if(vertexCount <= 0) {
// Easy memory leak here if we forget to delete mFaces before returning.
delete[] mFaces;
return;
}


And this would be a bad comment:

if(vertexCount <= 0) {
// Freeing up faces.
delete[] mFaces;
return;
}


Both comments say exactly the same thing, in which I prefer the _second_ one, since it is much more compact and to the point. It is namely obvious that we leak if we don't delete and obvious that the action is done before returning.

They don't say anywhere near the same thing. Second comment is redundant, as it says what is written in the code, and nothing else. First code explains why the code is written. It is not at all obvious that there will be a memory leak if the pointer is not release, because it can be owned by something else that is responsible for releasing it at the appropriate time. That is not obvious from the posted piece of code.

Understanding why something is done is important, and not something that can be conveyed easily in code sometimes.

Share this post


Link to post
Share on other sites
Quote:
Original post by Brother Bob
They don't say anywhere near the same thing. Second comment is redundant, as it says what is written in the code, and nothing else. First code explains why the code is written. It is not at all obvious that there will be a memory leak if the pointer is not release, because it can be owned by something else that is responsible for releasing it at the appropriate time. That is not obvious from the posted piece of code.


Yes it is. If it IS owned by something else, the whole code wouldn't exist and no comment would be placed. If it IS NOT owned by something else (self-owned), then the code DOES exist and it is obvious. So the existence of the deletion code is is telling you already: not deleted memory leaks (in this case), memory is owned by self, we do this before returning.

Now if the case would be that the deallocated memory is owned by something else, but is deleted here, a comment might come in handy. Or when something out of the usual goes on...the code presented is actually fairly common code.

Besides, if it IS worth commenting, the first comment should be more to the point IMO.

Quote:
Original post by Brother Bob
Understanding why something is done is important, and not something that can be conveyed easily in code sometimes.


True.

Share this post


Link to post
Share on other sites
Quote:
Original post by Decrius
Yes it is. If it IS owned by something else, the whole code wouldn't exist and no comment would be placed. If it IS NOT owned by something else (self-owned), then the code DOES exist and it is obvious. So the existence of the deletion code is is telling you already: not deleted memory leaks (in this case), memory is owned by self, we do this before returning.


I apologise in advance if I've misunderstood, but does RAII not make this moot?

I don't really understand the question above but the closest quandry I've ever had was solved by making use of the language's built in support for construction and destruction of local objects.

Sorry if I'm missing a more subtle point.

Share this post


Link to post
Share on other sites
Quote:
Original post by flodihn
For example this would be a good comment:


The focus is good, but the content is not. A C++ coder has no business editing such code while not knowing that we delete[] because "leaks are bad, mkay?" -- which is what the content boils down to. It's not like you're going to "forget" to delete[] "mFaces" "here" when you've already done it!

You might forget to delete something else, or delete mFaces someplace else, or some oddity of the surrounding code might make people think they should actually remove the delete[] -- but none of these issues are well addressed by the comment.

I'd rather know, say, why we have an early bailout (performace? later code that would crash with vertexCount==0?), or why we're not using RAII (even if only the implied "I'm too lazy to fix this" of a "// TODO: Use RAII instead")

Share this post


Link to post
Share on other sites
There are a number of reasons to add a comment into code.

1) As a reminder to yourself.
2) To explain a rather odd function to someone else.
3) To tell someone else reading your code something very important.
4) Documentation.

The initial posters comment block is one which is likely used for documentation purposes. Programs like Nautral Docs, and Doxygen read these comments and generate HTML and .chm help files which can help somewhat automate the process of documentation.

Is it a good idea? I suppose it depends, if your doing things just for yourself then it might be a good practice, but you won't see huge benefits out of it. If your writing a third party library then it can provide some assistance in generating documentation for function that the library users will want to use. And if your working in a company with other programmers then these types of comments are extremely useful when anyone new gets hired, or is working in an area of the code that is unfamiliar.

The downside to these style comments is that when you refactor your code you MUST make certian to update the comments. Fortunately things like Visual Assist help automate that process as well.

For future reference you can look at : http://www.possibility.com/Cpp/CppCodingStandard.html

This is a pretty good document on coding style guidelines. It's more of a good practices guideline than a "how to" book though.

Share this post


Link to post
Share on other sites
Quote:
Original post by Decrius
Quote:
Original post by Brother Bob
They don't say anywhere near the same thing. Second comment is redundant, as it says what is written in the code, and nothing else. First code explains why the code is written. It is not at all obvious that there will be a memory leak if the pointer is not release, because it can be owned by something else that is responsible for releasing it at the appropriate time. That is not obvious from the posted piece of code.


Yes it is. If it IS owned by something else, the whole code wouldn't exist and no comment would be placed. If it IS NOT owned by something else (self-owned), then the code DOES exist and it is obvious. So the existence of the deletion code is is telling you already: not deleted memory leaks (in this case), memory is owned by self, we do this before returning.

I'm not concerned about this example in particular, which in itself is kind of a bad example, but about the general idea of commenting intent and not action. First code comment intent, second code comment action. My argument is not in regards to this code, but in general.

Share this post


Link to post
Share on other sites
I'm not trying to make my code readable since I plan to be the only one working on it and it will be closed source. I'm just going to provide the library as an easy to use simple 3D game engine that can pretty much do anything. I was writing the comments as an in compiler documentation. I did this mainly because I thought if I were using the API and could get full documentation while programming with the API instead of needing to find the documentation online it would be better.

Share this post


Link to post
Share on other sites
Quote:
Original post by SteveDeFacto
I'm not trying to make my code readable since I plan to be the only one working on it and it will be closed source.


I'd say you're making a (beginners) mistake here. You will hate yourself next week / next month / next year when you need to refactor code you wrote now with the intend "I'm the only one working on it, so readability is no concern", because the speed is horrible and the features limited, and the client wants the product in 2 weeks and you have no time to rewrite it all, but it's such a mess!...

Share this post


Link to post
Share on other sites
Quote:
if(vertexCount <= 0) {
// Easy memory leak here if we forget to delete mFaces before returning.
delete[] mFaces;
return;
}

And this would be a bad comment:

if(vertexCount <= 0) {
// Freeing up faces.
delete[] mFaces;
return;

}



IMO neither comment is useful - the code itself is obvious in both cases. In this specific case, the place that needs commenting is the site of the new[] - why is the result not immediately being managed by a smart pointer / why isn't a container class being used? Those are the kind of things that needs commenting - non-idiomatic, non-obvious actions.

Share this post


Link to post
Share on other sites
It's turning into a common practice/standard to create documentation from comments at the top of programs/classes/copybooks or whatever buzz word is being used today to define a routine of programming commands to perform some function on components/structures/row sets of data.

So to "IMHO" the question have a comment type for documentation such as:


//==================================================
//=
//= this is the comment documentation block
//=
//==================================================

//
// this one is just a note to the other programmers
// about something complex within a routine
//




Then have a module to write out the //= from the source and you have documentation.

Share this post


Link to post
Share on other sites
Quote:
Original post by Decrius
Quote:
Original post by SteveDeFacto
I'm not trying to make my code readable since I plan to be the only one working on it and it will be closed source.


I'd say you're making a (beginners) mistake here. You will hate yourself next week / next month / next year when you need to refactor code you wrote now with the intend "I'm the only one working on it, so readability is no concern", because the speed is horrible and the features limited, and the client wants the product in 2 weeks and you have no time to rewrite it all, but it's such a mess!...


Exactly this happened to me when I took my first steps in C++. People here at GDNet said how much I suck at coding (kinda that [grin]), which made me realize my mistakes.

I still have a few codefiles written like crap in my project, but most of them are gone now. I just had some fun with deleting every file I didn't like. [wink]

So, I say to you, even if you hate me then:
Don't write shitty code like I did.


That means NOT that you have to delete everything now and write it again. I only did that because I didn't like the core design of my engine.
Just start with commenting functions now and you'll be fine, but don't overload them with comments.
A quick note what they do, like suggested here, should do it.

Share this post


Link to post
Share on other sites
Quote:
Original post by Hacksaw2201
It's turning into a common practice/standard to create documentation from comments at the top of programs/classes/copybooks or whatever buzz word is being used today to define a routine of programming commands to perform some function on components/structures/row sets of data.

So to "IMHO" the question have a comment type for documentation such as:

*** Source Snippet Removed ***

Then have a module to write out the //= from the source and you have documentation.


Why would you write documentation like that? that is really an eye sore. I wouldn't use any libraries written with that. Because I could easily just go find a library that uses Doxygen and generate html from it and browse it instead of wasting my time looking at yours.

Share this post


Link to post
Share on other sites
Quote:
Original post by SteveDeFacto
I notice that DirectX and many other professional APIs don't do this and this makes me wonder if it's a good idea. Is it a good or bad thing that I am doing this and why?


The only problem with tonnes of comments in headers is build times. A 'pro' library will take one of two routes:

1. Write all comments in the cpp files.
2. Write all comments in the header files.

Typically the comments will be written with doxygen (or other) markup and will be used to generate the code documentation. This can be problematic if the comments are in the source files, because you typically have to faff about for a bit to ensure only the relevant parts get documented (i.e. ensure internal code remains hidden).

If the comments are in the headers, then generation of the documentation becomes trivial, but this is at the expense of build times. The solution that most people would employ, is to write a pre-processor for the headers that strip all comments prior to the SDK (API/Lib/Whatever) being packaged in the installer.

Share this post


Link to post
Share on other sites

This topic is 2562 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this