
What I Wish I Had Known About Developing C/C++ From Linux Before I Started - derwiki
http://derwiki.tumblr.com/post/98651197/what-i-wish-i-had-known-about-developing-c-c-from
======
Periodic
When I started developing in C in Vim there are two things I've gotten used to
that I can't live without now: ctags and auto-complete (they help with
eachother).

Ctags is great, especially for navigating someone else's code. What does this
function do? Just ctrl-] and suddenly I'm at its definition. Something in
there I don't recognize, same thing. Ctrl-t to go back up the tag stack. Ive
become so used to navigating my code this way I have trouble without it.

Completion is just the way that Vim will give you completion matches in insert
mode if you hit ctrl-n or ctrl-p. With C it's very smart about it and will
automatically search included files. It's great for not having to worry about
exact spellings on things. If you really like this sort of stuff there are a
few plugins that do Textmate-like snippets.

~~~
barrkel
Of course, if you use an IDE, it can do all of this for you and much more, and
more accurately than ctags.

~~~
ori_b
Ctags is just as accurate at scanning C declarations as an IDE, and with a bit
of vim magic, it even auto-updates when you save files.

One thing to realize is that vim IS an IDE of sorts. Only, it's far more
extensible for the same effort. (although, from my brief forays with emacs,
emacs certainly beats vim for extensibility)

~~~
ramchip
Emacs also supports ctags. I didn't find it very useful with C++ though, which
is my usual language, since it didn't autocomplete member functions - I think
it's supposed to work, though I couldn't be pushed to tweak it.

Cscope, as commented on the article's website, sounds quite interesting too.

~~~
kingkongrevenge
ctags on C++:

ctags -R --c++-kinds=+p --fields=+iaS --extra=+q .

~~~
ori_b
ctags takes an environment variable for it's options, too:

    
    
        export CTAGS='-R --c++-kinds=+p --fields=+iaS --extra=+q'
    

and then you can just run 'ctags .'

------
mblakele
I use "screen" a lot, but I wish it had a better name. It helps if you search
for "gnu-screen", but not much.

Here's a tip that has saved me once or twice. If you start a long-running
process, but forgot to use screen or nohup, bash lets you 'disown -h' its
jobspec.

~~~
silentbicycle
One day I took the time to work this out for my .screenrc, and it's served me
well since:

    
    
      # Set up my status line at the bottom of every frame
      caption always "%{gb}  %{ck}%m-%d %C %{gb}  %{gb}%?%-Lw%?%{ck}%n*%f %t%?(%u)%?%{gb}%?%+Lw%?"
    

All of the %{gb} things are color codes. It looks like this:
<http://shenani.gen.nz/~scott/screen-statusbar.png>

Binding ! @ # etc. to select 10, 11, 12, ... is handy, too.

~~~
joeyo
There are more .screenrcs (including my own) in this thread:
<http://news.ycombinator.com/item?id=425890>

------
atypic
There is one thing I feel have been neglected here: Debugging.

Debugging C in Linux is a dream with gdb. Debugging (heavily templated) C++ in
gdb is a nightmare.

I therefore have one additional tip, though it doesn't work in console: Run
Visual Studio in wine. It's debugger can pick up running Linux processes and
is awesome to work with.

~~~
dryicerx
I feel the same way about GDB lacking in C++. I ran across project Archer...
apparently better debugging support for C++

<http://sourceware.org/gdb/wiki/ProjectArcher>

------
keefe
This is a nice list! However, I really think that increasing speed of
development with better tools is a cornerstone of being one of those elite
programmers, and vim<<eclipse, at least for Java! I haven't done C/C++ for
some time... but I expected similar IDEs exist. "The way our development
environment is set up though, there was really no good way to use Eclipse
because everything is done on a remote development box, and they won’t let us
run Eclipse and forward over X (which is reasonable; Eclipse has a lot of
overhead)" I think this is just a horrendous setup and unless there is some
compelling reason (e.g. scientific computing on a cluster? even then...) that
there should be a much cleaner separation between development boxes and
production boxes and most of your code should be developed on a local box with
some canned data for testing and then pushed out to production when that is
done. This may require some effort, but the decrease in turnaround time for
changes will be worth it in almost every scenario.

~~~
dkarl
Unfortunately, your expectations would not be met. IDEs make up for their
limited text-editing features by providing language-dependent, code-aware
functionality. Because C++ is such a hairy language, IDEs aren't able to do
much with it. They don't give you anything like the cushy, comprehensive
support that IDEs provide for Java. With C++, giving up the relatively lame
IDE features to get a powerful text editor is a no-brainer. (I use Eclipse for
Java and emacs for everything else.)

You're absolutely right about their development environment; it's adapted for
one set of tools. It doesn't necessarily mean other tools are inferior in
general, as the author seems to conclude.

~~~
keefe
I find this post highly questionable. What is so hairy about C++ for an IDE
exactly? It's strongly typed and yes, if you do too much C style stuff it may
be a bit harder to navigate but if you stay in a clean OO world it should be
very, very similar to Java. Microsoft put out a competent C++ IDE well over a
decade ago and Borland has done so as well... It's my personal opinion that
IDEs are in general superior to text editors because this integration reduces
the cognitive load of solving particular programming problems. People that say
eclipse doesn't have a good text editor are being a bit ridiculous - out of
the box it is not that great, but there are many 3rd party editor plugins, you
could configure shortcut keys however you want and of course extend eclipse...
now I am somewhat biased in that I work daily on an eclipse RCP project, so I
am already spun up on extending eclipse. This all has me curious though, I'll
spin up eclipse C++ development against my thesis code the next (likely
imaginary) opportunity I have time to kill...

~~~
hfinucane
To write a good C++ IDE, you need to deal with macros, C++'s obscene syntax
(There are what- four complete C++ parsers?), and you need to parse all sorts
of Makefiles, or else no existing projects will work.

~~~
keefe
I'd expect some games that had to be played with release engineering. If the
code is properly modularized, this could be two separate processes where you
develop your module with mock data and then deploy it into production. Is the
opinion really that all the current IDEs suck - <http://msdn.microsoft.com/en-
us/visualc/default.aspx> , <http://www.eclipse.org/cdt/> ,
<http://www.netbeans.org/features/cpp/> ,
<http://www.bloodshed.net/devcpp.html> and all the 2nd tier as well? Maybe I
am too deep into Java and eclipse, but it seems there are genuine advantages
to using IDEs and C++ is similar enough to java that at least for some subset,
such a tool could be created. If not, that certainly seems like a market...

~~~
hfinucane
C++ does look similar to Java, but it's really not. Preprocessor magic +
template magic + linking magic means pain.

I will admit to not having tried devc++ or visualc. I would imagine that
visualc might be able to solve the problem, since they can control the build
system, and can hook into their compiler directly (last I checked, GCC made
this very hard).

I'm also going to go out on a limb and suggest that you may be overestimating
the pain points other people experience /not/ using an IDE.

~~~
keefe
I haven't done professional work in C++ only my thesis project which was
relatively self contained and simple, so maybe I am underestimating the
importance of preprocessor/template/linking magic. There is certainly a rather
large barrier to entry for vim/emacs for the average developer.

------
davidw
strace is another extremely useful tool. Sometimes it's really nice to be able
to see exactly what's happening at the OS/program boundary (what _exactly_ are
we reading from the file? from the network?), and strace can do that in a very
non-intrusive way - no root reqired, no recompile required.

~~~
jbert
Seconded. That apache process is chewing cpu, is it spinning in an inf loop
internally to userspace? No, strace shows it repeatedly doing backend
conn/op/disconnect - aha!

Another trick in this vein is/was to use 'pstack' to pull a C backtrace from a
looping process. If you do that every second for 10 secs, you'll probably find
where the process is looping. As a bonus, it also acts as a poor-
man's-retroactive profiler (process X intermittently takes 30s to handle it's
job instead of 2s - watch for one and when it happens, strobe the process with
pstack to see what it's up to). Can be used in production, no need to deploy
profiling build and run for ever to catch problem, etc.

(And a variant of this trick for interpreted languages is to hook an unused
signal (SIGUSR2?) in your language to say "dump me a perl/python/etc backtrace
to the log file". Assuming the loop is in your app code this will give you a
language-level backtrace if you strobe the process with the signal)

NB1: pstack doesn't do anything which scripted gdb couldn't do, it's just more
convenient

NB2: pstack is unavailable on 64-bit arches?

NB3: pstack needs some symbols to work with in the binary, which probably
won't be the case with your system apache+mod_xxx

------
mahmud
Worse is NOT Better; use a safe and high-performance programming language and
learn its foreign-function interface to call out to C and C++. Life is too
short for core-dumps and premature optimization, plus you only have two feet
to shoot at.

The better designed a language the better its development process feels. You
can get immersed in a lowly Lisp, J, or Forth listener. Just a little black
xterm with nothing else to it, and you feel productive already (never mind the
amazing environments there are for Lisp.) BADLY designed and malignant
languages have 3rd party tools to augment its functionality. There are things
to bolt on, hammer in and stuff to bake into the scaffolding before you stuff
in boxes. The C and C++ equivalent of a listener is `cat` or maybe the system-
shipped vi or nano or pico. Can you seriously feel yourself getting something
done?*

* (I will answer myself and say yes; I learned Unix programming over a serial line, but it was not an immersive experience; I had books on my desk and lap and was flipping back and forth to get anything done; a masochistic sort of fun, fueled by the mischievous possibility of breaking into another account ;-)

~~~
kmavm
Since you mention core dumps, please take some unsolicited feedback from an
old C programmer: the post-modern "developer productivity" family of
languages' lack of core dumps is a bug, not a feature. You _want_ core dumps.
They're the right thing. They let you debug a broken program that has since
been restarted, or on a different machine than the crash happened, six months
afterwards.

Even if you program in a safe language, you still want assert(), and when that
assert fails, you _don't_ want an exception: once the exception has torn down
a single frame it's too late, since you lose the precious "can't happen"
program state.

Sure, C is a low-level language, but I think the YC consensus insufficiently
weights the quality of tools supporting this ecosystem. Debuggers and
profilers are indispensable, high-leverage tools for saving developer time,
and the hip languages these days have followed perl's lead in just sticking -d
and -p flags in the reference implementation and pretending the problem is
solved.

~~~
mahmud
"the post-modern "developer productivity" family of languages' lack of core
dumps is a bug"

Lisp doesn't dump core, it will drop you in a debugger prompt where you can
Frankenstein your programmer to life as you wish. Forget Lisp, Scheme and
other languages with full continuations will give you the entire run trace of
your program in a video tape, where you rewind and fast-forward as you wish. C
is not a language whose control semantics you want to brag about.

But back to Lisp, here how you "dump core" in Common Lisp: write a handler for
the error condition and call SAVE-LISP from there. One line of code, left
optional to the programmer.

"you still want assert(), and when that assert fails, you don't want an
exception"

Yeah, it's called by the exact same name in Common Lisp.

"Debuggers and profilers are indispensable"

My Common Lisp has both a deterministic and an statical profiler. Standard
Common Lisp has GC, TRACE, ROOM, DESCRIBE, APROPOS, ED, DISASSEMBLE and TIME
among others. Those correspond to malloc/free, gprof, ltrace, man, apropos,
vim and objdump; in the friken LANGUAGE :-) Everything is tied together with
function called semantics and a memory visible to all; not with brittle
"shell" languages and text parsing. The vendor and community extensions will
make you weep.

There is really no point of comparing Lisp to C; you should compare Lisp to
Unix.

~~~
kmavm
FWIW, I don't consider CL a member of the "developer productivity" gang of
languages. In practice, it is much more like a better C than it is like
python: you have C's relative poverty of libraries and richness of tools.

Still, I meant what I said.

"Lisp doesn't dump core, it will drop you in a debugger prompt..."

What if the user isn't a developer, but, y'know, a user? On the other side of
the country, who doesn't care why your code is broken? Will you fly to their
site? Hope they let you ssh in and not restart the application while you
personally debug it? Hmm, if only it were possible to somehow _serialize_ the
state of the broken program, so that someone else could debug it in a
different time and place ;).

~~~
mahmud
You didn't read what I wrote earlier, so here is your Lisp core dump:

    
    
      (handler-bind ((error #'(lambda (e)
            (save-lisp-and-die "lisp.core"))))
               (YOUR-PROGRAM-ENTRY-POINT))
    

Autopsy is not that hard with Lisp ;-)

~~~
kmavm
You're absolutely right that I skipped a whole paragraph of your reply; mea
culpa.

~~~
mahmud
+1, no problemo hermano!

------
gvb
"diff: pretty standard utility, but this is what I use it for: I loop through
all the files I’ve modified and diff to the previous version, then pipe to a
grep where I can search for something I think I’ve changed but can’t remember
where."

NOOOOOOooooooo. That implies he is using ad-hoc version control (uniquely
named files or directories with non-revisioned copies).

Tracking and finding changes is what git is for. Commit early and often! If
you mess up, it's got your back! If your compatriots use SVN, that works, but
not nearly as well (when I used SVN, I would still revision control my local
copies with RCS in between SVN commits). If you are developing by yourself,
rcs is the minimum acceptable alternative.

------
johnrob
Anyone else find themselves typing this way too often?:

awk '{print $2}'

Is there a way to achieve this that's easier to type?

~~~
ori_b
cut -d'delim' -f'fieldno'

------
Raphael_Amiard
I guess the big drawback for theses kind of tools for me is the time it takes
to setup a nice developpement environnement. To fine tune my vim as i like it
with ctags completion , good keybindings, a nice colorscheme and all, it takes
me around 5 hours minimum.

I'm currently dev'ing for QT under QT Creator, and everything is nicely
integrated, with some really neat features you can't reproduce in vim, and it
even has an (incomplete) vim emulation mode !

I used to be an hardcore vim / cli fan, but i'd go back to that for nothing in
the world now, at least for this current dev setup. Also i hate having to mess
with makefiles.

------
dkarl
c++filt - an absolute necessity.

Also, he should have just pointed out that all IDEs are ass for C++. Java is
simple enough that an IDE can be a big help, but C++ is too complicated and
too slow to compile. (The remote access thing is just a matter of the work
environment being adapted to one set of tools and not another -- the real
issue is that text editors beat IDEs for C++.)

Otherwise, an excellent list.

~~~
silentbicycle
The _real_ issue is that C++ is too complicated and too slow to compile.

Languages that are easier to throw together a reasonable parser for (Lisps,
Smalltalk, Lua, or even C) have a much lower barrier to entry for development
tools. Keeping the language syntax simple enough means that somebody
scratching an itch can write something useful in an afternoon or a weekend,
rather than taking a team and months.

~~~
fix3r
Actually, no. The real issue is using compiler's front-end from the IDE
itself. While it's true that C++ is hugely complex IDE writers shouldn't try
to replace compilers (ie. trying as hard as they might they'll never get
around C++ templates and their touring-completeness). MS got this right. gcc
and every IDE that relies on it (like Xcode) is crippled in this regard.

~~~
silentbicycle
GCC _is_ crippled in that regard, but it's a problem with gcc itself. It's
written (perhaps deliberately) in a manner which makes it difficult to just
use parts of it, e.g. just the back-end for code generation.

For an example of a less accidentally complex way to do what C++ templates do,
look at ML's functors.

------
messel
I started with makefiles and emacs but fell in love with Visual C++ and
eventual .NET. Netbeans is aok, but the article has prompted me to review "the
impossible" and check out yet another interface.

My ideal user interface for programming? A brilliant group of younger smarter
coders with better memory.

------
hboon
There's an incremental find option in Eclipse. Ctrl-j or was it Ctrl-i (or
something like that) which is pretty nice and I wish all IDEs (read: IDEs)
have that. That beats Ctrl-F any day.

How did you do refactorings? Or you just don't?

~~~
jballanc
In Vim, install ack, then put "set grepprg=ack" in your .vimrc. Then, open
your project in Vim, do a ":grep <your-symbol-here>", and use ":cn", ":cnf",
":cp", ":cpf", ":cr", etc. to move about. Combined with strong knowledge of
setting marks and using ":s/" substitutions, and I often wonder how people who
use IDEs do refactorings! ;-)

~~~
miloshh
I think you misunderstood what refactoring means in an IDE. Suppose you want
to rename a method. There might be many other methods of the same name in
different classes, local variables of that name in other methods, or even
classes with that same name in differen packages. Eclipse automatically does
all of this for you.

I honestly don't understand how regexps and strong bookmarking skills could
help you - the editor needs true knowledge of the language to carry out this
task.

~~~
kingkongrevenge
I doubt it's realistically possible for this to work reliably with C++. How
could the parser deal with a predeclared type pointer in a header file that is
resolved at link time? How about unions?

------
bcl
Good list of tools. All of those usually show up on any Linux developer's list
of what's in their toolbox.

------
bf
Why are we taking C/C++ programming advice from somebody who has been doing it
for just over a year?

And not to troll, but anyone who honestly believes vim is a better development
environment than one of the mature Linux IDEs (Eclipse, Code::Blocks,
KDevelop) is an idiot.

~~~
mahmud
My development environment runs 24/7 and I can get to it from ANY machine on
earth.

ssh me@mysite.com

$ screen -x

Even the cursor stays where it was between sessions.

How can I do that with ${IDE}?

~~~
eru
Shouldn't this be possible with remote sessions of X or so?

~~~
silentbicycle
Yes, but screen is usually good enough for most people (self included), and is
quite trivial to set up.

------
zandorg
I just use Kdevelop.

