Do you add information to the top of each .hpp/.cpp file? [closed] - c++

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 6 years ago.
Improve this question
When creating a new C++ header/source file, what information do you add to the top? For example, do you add the date, your name, a description of the file, etc.? Do you use a structured format for this information?
e.g.
// Foo.cpp - Implementation of the Foo class
// Date: 2008-25-11
// Created by: John Smith
One team I know embeds CVS commit messages to the foot of each file, but I'm not sure I want to go this far...

Information about who created a file and when and who edited it and when is all in source control. If your team has good practices around check-in comments, then you'll know the reasons for each change too. No need for comments for that stuff.
I think it's 100% legit - wise, even - to put a comment block, as long as is necessary, explaining the purpose of the class/module. When the next person goes to change it, they'll have a better idea of the overall vision and whether this file is the appropriate place for their change.
Some shops put copyright notices and other legal folderol in source file comments. This strikes me as just silly - if your (non-OSS) source code has made it onto someone else's servers without your knowledge or permission, a copyright notice is probably not going to deter them from doing anything with it. IANAL, YMMV.

Don't. Most of the stuff can be retrieved from the versioning system when needed so it's redundant to add. That would leave you with the description of the content of the file but that's part of the class documentation most of the time (or at least the documentation of the specific type).
I don't do any of those, but then again, I don't like the cruft.

We're required to put copyright information at the top of each file. I think dates, authors, and the name of the file is a waste of time.
We also have our source control system append check-in comments at the bottom of each file. I initially hated the change log, but over time I learned to like it. It really helps when merging changes.

I include the file name, a brief description of the file's purpose, and a $Id$ tag for CVS or Subversion purposes. File creator and date of creation can be found by checking the repository, so it's not needed.
File name is included because depending on what you're using to edit the file, that might not be entirely apparent when you're editing it. The description can be used to determine if a bit of code belongs in the file, or if it should be moved to another. And of course, $Id$ gives you last change time, and last editor.
Embedding check-in messages is only useful when the message is useful, and only if the file is updated once and a while. Including every message will simply bloat the file to the point where there's more comments describing changes than there is actual code. Best to leave that to the repository as well; often it's only a short command line to get the file's check-in log.
If you're stuck with a revision control system that can't keep history for moves and copies, in that case just reference the original file and its version number. Of course, if you're using a system that was created sometime in this century and not the last, that shouldn't be an issue.

I used to like putting version control keywords in the header of file. But recovered from that affliction. :) For two reasons:
Nobody put comments in that are of any use. You always wind up looking at the diffs reported by the version control system.
It creates a nightmare in trying to diff large filesets because the keywords create differences that are the only difference in the file.

Originally answered here, but since deleted: 134249
I would only put two things:
licensing/copyright information
comments required by documentation-generating tools (i.e., the comments have to be in the header to work - otherwise, they should go in the definition files)
Anything else is unnecessary fluff that won't be maintained, and will eventually become worse than nothing at all.
At the time I worked for a large defense company, and we had draconian coding standards. If you followed them to the letter (and most people don't), most of your headers would be composed mostly of that meaningless fluff. Doubly worse is that the exact same fluff is required to be placed in source files as well, which means two copies of the fluff gets out of date and becomes misleading.

I don't embed the date because it's redundant. If someone wants to know the date a file was created don't trust the author, trust your source control system. It should be the defintive answer for the date of creation.
I'm definately not against embedding check in messages though. Those are pretty useful.

We use our RCS to automatically stamp the following on the file:
Copyright,
RCS file name,
Date modified,
Author of last change,
RCS revision number
I think this is very convenient. I really like having the file name automatically populated in each file, because it makes searching the solution for files very quick.

This is what i normaly put at the top of files:
///////////// Copyright © 2008 DesuraNET. All rights reserved. /////////////
//
// Project : [project name]
// File : [file name]
// Description :
// [TODO: Write the purpose of ... ]
//
// Created On: 11/12/2008 2:24:07 PM
// Created By: [name] <mailto:[email]>
////////////////////////////////////////////////////////////////////////////
and i set up a macro in vis to do add it in and fill in default info when i make a new file

If you're using CVS, check out it's keyword substitutions. They will help automate embedding that information.
Personally I stick this at the top of all of my source files:
// $Id$
Other informative comments I embed to be parsed with doxygen, if they relate to something specific (the file, the class, a type, etc).

i generally only add any "comment info" when...
i don't think i'll remember or its not obvious what something is doing
or
when i release the source code and i actually want others to be able to use/learn from it.

I usually include a description of the purpose of the code found in that file. Everything else seems to be handled elsewhere: dates and comments in source control, etc.

Everyone is saying that your source control will have the date and programmer info, but that isn't always true. I worked in a shop that used Source Safe, and it was fine until someone decided to move a file to a different location. At that point, it essentially became a new file according to SS, and no previous history existed.
Perhaps because of that, the programmer name and date were automatically added to the comment section at the top of the file. When there got to be more than about 10 entries, we'd strip out all of the middle ones, leaving only the original date and author, and the current information.

A copyright statement for my client ;-)

We use MSVC & VSS and have a plugin that adds any comment you specifiy at check-in to the file that's being checked in as a comment. It's very convinient to look at the top of the CPP file to find out the bug-tracking ticket number that a change was made for.

I use Subversion.
Here's what I like to put near to the top.
$Id$
$HeadURL$
That substitutes the revision, last editor, and then the location of the file in the repository. Although I always work from working copies, this lets me print/email a file and look at it later to know exactly where it came from. $HeadURL$ especially is nice because it tells what project and branch the file is in and how to get to it (nice with larger nested subpackages and the like).
Agreed on the uselessness of big manual comment blocks — although docstrings/Javadocs are recommended — and on automatically appending the commit log.
It sounds like some of you are using terrible VCSes, if you are getting diffs or merge conflicts generated by the keywords themselves. Subversion handles it well.

Related

Using a Main program to edit all program headers in a directory?

I have frequently encountered the following issue in my day to day programming at the office where files can be reused from one project to the next, but the header information needs to be updated for each file, when you are dealing with hundreds of files updating them all manually is a pain, and a waste of resources.
Ideally what I would like is a program that contains a standard header with attributes like author, project code, creation date etc, that I can manually update and when executed it will add this information to all the files/programs in a directory. We use a standard header, which cover the first 20 lines of each program and each attribute is on a certain line, or can be searched for in order to replace it.
For the most part I would like to develop this myself, but any starting point as to how to apply said header to the first 20 lines of each program and how to apply it to each file in a directory. I want to add other functionality later for tracking purposes etc, but for now any help in getting started would be awesome.
I'm a big fan of using keyboard macros to generate header shells. So when I hit CTRL-H, I get a header block comment with the sort of information you described, including my name and today's date. If the assumption is that you will have to manually type something into a header for every program for every project (e.g. a revision note or whatever), then automatically adding 100 header shells doesn't save you much more than the keyboard macro approach.
That said, yes, you could do it with SAS using file statement or whatever. Could probably do it with any good text editor.
And of course a better solution would be to get a version control system.
I wouldn't modify the programs in the directory this way, but rather use %include files. We've done that on projects before, where you have a single program that includes libnames and such, and then you have
%include('header.sas');
or whatever in every program you write in that project. Modifying the code programmatically like this is a bad idea, both because you might not have the most up to date version of the headers, and because it risks damaging the programs if you do it incorrectly). Putting it as an include is easy, avoids replicating the same code 20 times (with possibility of error), and guarantees up-to-date code.
In your case, you can modify the 'header' file for the new day, and assuming you've set things up properly (which it sounds like you have), then the 100 or whatever other programs all can stay the same, unchanged, just including the updated header (automatically). This has the added advantage that you don't make lots of tiny changes to the programs, meaning you know when a meaningful update to the program occurred (as opposed to just a daily run).
In general, this modular approach is superior - divorcing the 'individual run' part of a program/process from the main part - because of these reasons, and because it makes it easier to reuse programs for other purposes as well if you have it set up so the module is already prepared and just needs a header file in the same directory to automatically run. (You can get the name of the current program and its path; if you need that, comment with what mode you use - batch or interactive - and what OS you are in).
This is also one of the places where the Enterprise Guide model is a bit better; there you have all of your project-related files in one project file (.egp), so you don't have to do even this - the project itself can have an autoexec process flow (which runs first, to set libnames and such) and can have notes/author/etc.
This should work. If a line starts with "Author:" it replaces the line with "Author: ME, ONLY ME!!!".
If you are on Windows, change all the forward slashes ("/") to backward slashes ("\").
%let infolder=/folder/where/sas/programs/are;
%let outfolder=/folder/where/new/sas/programs/are/going;
filename dummy temp;
data _null_;
attrib currentinfile currentoutfile length=$32000;
infile "&infolder/*.sas" filename=currentinfile lrecl=32000;
input;
currentoutfile="&outfolder./"!!scan(currentinfile,-1,"/");
file dummy filevar=currentoutfile lrecl=32000;
if index(_infile_,"Author:")=1 then put "Author: ME, ONLY ME!!!";
else put _infile_;
run;

What's wrong with this user ignore file for Mercurial?

A little retrospective now that I've settled into Mercurial. Forget forget files combined with hg remove. It's crazy and bass-ackwards. You can use hg remove once you've established that something is in a forget file that isn't forgetting because the item in question was tracked before the original repo was created. Note that hg remove effectively clears tracked status but it also schedules the file for deletion in anything that gets changes from your repo. If ignored, however the tracking deactivation still happens but that delete-me change set won't ever reach another repo and for some reason will never delete in yours which IMO is counter-intuitive. It is a very sure sign that somebody and I don't know these guys, is UNWILLING TO COMPROMISE ON DUH DESIGN PROBLEMS. The important thing to understand is that you don't determine what's important, Mercurial does. Except when you're merging on a pull of course. It's entirely reasonable then. But I digress...
Ignore-file/remove is a good combo for already-tracked but very specific files you want forgotten but if you're dealing with a larger quantity of built files determined with broader patterns it's not worth the risk. Just go with a double-repo and pull -u from the remote repo to your syncing repo and then pull -u commits from your working repo and merge in a repo whose sole purpose is to merge changes and pass them on in a place where your not-quite tracked or untracked files (behavior is different when pulling rather than pushing of course because hey, why be consistent?) won't cause frustration. Trust me. The idea that you should have to have two repos just to get 'er done offends for good reason AND THAT SO MANY OF US ARE DOING IT should suggest a serioush !##$ing design problem, but it's much less painful than all the other awful things that will make you regret seeking a sensible alternative.
And use hg help. It's actually Mercurial's best feature and often better than the internet (which I don't fault for confusion on the matter of all things hg) for getting answers to everything that is confusing and counter-intuitive in this VCS.
/retrospective
# switch to regexp syntax.
syntax: regexp
#Config Files
#.Net
^somecompany\.Net[\\/]MasterSolution[\\/]SomeSolution[\\/]SomeApp[\\/]app\.config
^somecompany\.Net[\\/]MasterSolution[\\/]SomeSolution[\\/]SomeApp_test[\\/]App\.config
#and more of the same following
And in my mercurial.ini at the root of my user directory
[ui]
username = ereppen
merge = bcomp
ignore = C:\<path to user ignore file>\.hgignore-config
Context:
I wrote an auto-config utility in node. I just want changes to the files it changes to get ignored. We have two teams and both aren't on the same page with making this a universal thing so it needs to be user-specific for now.
The config file is in place and pointed at by my ini file. I clone. I run the config utility and change the files and stat reveals a list of every single file with an M next to it. I thought it was the utf-8 thing and explicitly set the file to utf-16 little endian. I don't think I'm doing with the regEx that any modern flavor of regEx worth actually calling regEx wouldn't support.
The .hgignore file has no effect for files that are tracked. Its function is to stop you from seeing files you want ignored listed as "untracked". If you're seeing "M" then they're already added (you got them with the clone) so .hgignore does nothing.
The usual way config files that differ from machine to machine are handled is to put a app.config.sample in source control, have app.config in .hgignore and have people do a copy when they're making their config edits.
Alternately if your config files allow for includes and overrides you end them with include app-local.config and override any settings in a app-local.config which you don't add and do include in .hgignore.

sketch flow -- how do we rename .xaml and .cs files without breaking sketchflow map?

how do we rename .xaml and .cs files?
would like to be able to keep development in synch with the original sketchflow. i.e. sketchflow has features such as the ability to collect client feedback on a per screen basis, etc.
... I kind of answered my own question here, so I'll post it as a follow up. Asked the original question 9 hours ago on the MS site without response... still trying to work out where the best place is to talk to the community, so sorry for the duplicate.
THE ANSWER (IS THERE A BETTER ONE?)
Context: Sketchflow is a prototyping tool. In large teams possibly you want to keep the prototype seperate from the finished version, or there's a large prototyping phase.
My view is that I really like Sketchflow. It's one of the coolest things I've seen for a while (well done Microsoft).
... so for me, I want the prototype to become a the finished product. I want the designers to step in and make transitions whenever they want. I want the designers to kick the process off, and the developers to put in the detail. I'd like our customers to be able to post feedback at any time during the build process. btw: get your developers to check out MVVM. It's very cool.
My bet is that the feedback could get lost if you make a breaking change (a file rename) -- so just beware of that. That wont be a problem for us. We'll get our file names to make sense and then mostly leave it alone. Of course MS could fix this this by creating a globally unique id (Guid) for each screen that is created. Perhaps they've done this already. If someone from MS reads this, please put this on your requested features list.
THE ANSWER:
So here is the answer that works for me:
don't try to hand-edit the xaml / cs, as all the cross referencing that you might be doing with behaviors will break if you aren't really careful. Typical files that need to be modified: .csproj, Sketch.Flow, xxxx.xaml, and xxxx.cs.
To auto do it, download a tool like Ultraedit. Alternatively, you might be able to just use VS 2010 (untested).
Steps with ultraedit:
(BACKUP YOUR PROJECT FIRST)
Search/Replace In Files...
Find in files... "Screen_1_19"
Replace with... "Welcome"
In Files/Types... "."
Directory...
Match Whole Word Only
Hit "Start"
follow the prompts
rename the files (.xaml & .cs) to be Welcome.???? (where ???? is .xaml or .cs) . Since I use SVN, this step gets done for me in one step (no big deal).
If using VS2010 for steps 1 through 8, be careful do longer string replacements first e.g. Screen_1_19 before Screen_1. I think VS treats _ as a word break. On ultraedit you'll be fine.
If there's interest, in the spare time that I don't currently have, I could release a quick tool to do this on codeplex.
** note: because we are working with XML and XML is very particular about being correct, I close expression blend down, and then reopen it again after the replace/rename to see if I was successful + my screen map still has all the flow lines still drawn in.
answer is above in the body of the question.

Scan for changed files

I'm looking for a good efficient method for scanning a directory structure for changed files in Windows XP+. Something like how git does it is exactly what I'm looking for, when running a git status it displays all modified files, all new (untracked) files and deleted files very quickly which is exactly what I would like to do.
I have a basic model up and running which performs an initial scan and stores all filenames, size, dates and attributes.
On a subsequent scan it checks if the size, attributes or date have changed and marks as a changed file.
My issue now comes in detecting moved and deleted files. Is there a tried and tested method for this sort of thing? I'm struggling to come up with a good method.
I should mention that it will eventually use ReadDirectoryChangesW to monitor files and alert the user when something changes so a full scan is really a last resort after the initial scan.
Thanks,
J
EDIT: I think I may have described the problem badly. The issue I'm facing is not so much detecting the changes - I have ReadDirectoryChangesW() using IOCP on multiple threads to detected when a change happens, the issue is more what to do with the information. For example, a moved file is reported as a delete followed by a create and a rename comes in 2 parts, old name, followed by new name. So what I'm asking is how to differentiate between the delete as part of a move and an actual delete. I'm guessing buffering the changes and processing batches would be an option but feels messy.
In native code FileSystemWatcher is replaced by ReadDirectoryChangesW. Using this properly is not simple, there is a good baseline to build off here.
I have used this code in a previous job and it worked pretty well. The Win32 API itself (and FileSystemWatcher) are prone to problems that are described in the docs and also discussed in various places online, but impact of those will depending on your use cases.
EDIT: the exact change is indicated in the FILE_NOTIFY_INFORMATION structure that you get back - adds, removals, rename data including old and new name.
I voted Liviu M. up. However, another option if you don't want to use the .NET framework for some reason, would be to use the basic Win32 API call FindFirstChangeNotification.
You can use USN journaling if you are up to it, that is pretty low level (NTFS level) stuff.
Here you can find detailed information and source code included. It is written in C# but most of it is PInvoking C/C++ functions.

C++ Directory Restructuring

I have a source code of about 500 files in about 10 directories. I need to refactor the directory structure - this includes changing the directory hierarchy or renaming some directories.
I am using svn version control. There are two ways to refactor: one preserving svn history (using svn move command) and the other without preserving. I think refactoring preserving svn history is a lot easier using eclipse CDT and SVN plugin (visual studio does not fit at all for directory restructuring).
But right now since the code is not released, we have the option to not preserve history.
Still there remains the task of changing the include directives of header files wherever they are included. I am thinking of writing a small script using python - receives a map from current filename to new filename, and makes the rename wherever needed (using something like sed). Has anyone done this kind of directory refactoring? Do you know of good related tools?
If you're having to rewrite the #includes to do this, you did it wrong. Change all your #includes to use a very simple directory structure, at mot two levels deep and only using a second level to organize around architecture or OS dependencies (like sys/types.h).
Then change your make files to use -I include paths.
Voila. You'll never have to hack the code again for this, and compiles will blow up instantly if something goes wrong.
As far as the history part, I personally find it easier to make a clean start when doing this sort of thing; archive the old one, make a new repository v2, go from there. The counterargument is when there is a whole lot of history of changes, or lots of open issues against the existing code.
Oh, and you do have good tests, and you're not doing this with a release coming right up, right?
I would preserve the history, even if it takes a small amount of extra time. There's a lot of value in being able to read through commit logs and understand why function X is written in a weird way, or that this really is an off-by-one error because it was written by Oliver, who always gets that wrong.
The argument against preserving the history can be made for the following users:
your code might have embarrassing things, like profanity and fighting among developers
you don't care about the commit history of your code, because it's not going to change or be maintained in the future
I did some directory refactoring like this last year on our code base. If your code is reasonable structured at the beginning, you can do about 75-90% of the work using scripts written in your language of choice (I used Perl). In my case, we were moving from set of files all in one big directory, to a series of nested directories depending on namespaces. So, a file that declared the class protocols::serialization::SerializerBase was located in src/protocols/serialization/SerializerBase. The mapping from the old name to the new name was trivial, so that doing a find and replace on #includes in every source file in the tree was trivial, although it was a big change. There were a couple of weird edge cases that we had to fix by hand, but that seemed a lot better than either having to do everything by hand or having to write our own C++ parser.
Hacking up a shell script to do the svn moves is trivial. In tcsh it's foreach F ( $FILES ) ... end to adjust a set of files. Perl & Python offer better utility.
It really is worth saving the history. Especially when trying to track down some exotic bug. Those who do not learn from history are doomed to repeat it, or some such junk...
As for altering all the files... There was a similar question just the other day over at:
https://stackoverflow.com/questions/573430/
c-include-header-path-change-windows-to-linux/573531#573531