undefined reference

Pages: 12
Helo,

i'm writing a program, that consists of 4 files. I'm using g++ as a compiler. The problem is, that i'm getting these messages when trying to compile:

/tmp/cckuMyrX.o: In function `main':
Main.cpp:(.text+0x1a9): undefined reference to `ChainedList<int>::ChainedList()'
Main.cpp:(.text+0x202): undefined reference to `ChainedList<int>::insertAfter(Node<int>&)'
Main.cpp:(.text+0x25e): undefined reference to `ChainedList<int>::insertAfter(Node<int>&, Node<int>&)'
Main.cpp:(.text+0x2cf): undefined reference to `ChainedList<int>::getNode(int)'
collect2: ld returned 1 exit status

The exact command i'm using is simply "g++ Main.cpp ChainedList.cpp".

The 4 files are: Main.cpp, ChainedList.cpp, ChainedList.h, Node.h
Main.cpp contains the main function, while ChainedList.h and .cpp contain a template class. Node.h is a type, that is required for the ChainedList type.

This is Main.cpp:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif

#include <iostream>
#include <cstdlib>
#include "Node.h"
#include "ChainedList.h"

using namespace std;



int main(int argc, char *argv[])
	{
		cout << "Helooooo";
		ChainedList<int> lista;
		Node<int> eredmeny;
		Node<int>* elem = new Node<int>;
		Node<int>* mutato;
		int n,szam;

		cin >> n;

		cin >> szam;
		(*elem).Data = szam;
		(*elem).Next = 0;
		lista.insertAfter(*elem);
		mutato = elem;
		elem = new Node<int>;
		

		for (int i = 1;i < n;i++)
			{
				cin >> szam;
				(*elem).Data = szam;
				(*elem).Next = 0;
				lista.insertAfter(*mutato,*elem);
				mutato = elem;
				elem = new Node<int>;
			}


		cout << "Hanyadik Node-ra vagy kivancsi ?" << '\n';
		cin >>n;


		eredmeny = lista.getNode(n);
		cout << "Eredmeny: " << eredmeny.Data << '\n';
		

		//Kell egy eljárás, ami kitörli a teljes listát
		delete elem;
		delete mutato;	
		return EXIT_SUCCESS;
	}
ChainedList is a template class. It seems to be declared in a header and implemented in a compilation unit. Unless your compiler supports the "export"-keyword (which it doesn't) you have to provide the implementation in the header.
Last edited on
It seems to be declared in a header and implemented in a compilation unit.


That's correct.

Unless your compiler supports the "export"-keyword (which it doesn't) you have to provide the implementation in the header.


Originally the implementation was in the header, and then there were no errors. I deceided however to put the implementation in a different source file. If g++ does not support this, what compiler does ?
I have heared rumors that there is one compiler available supporting 'export', I don't remember which one it is, though. If you want to write portable code, don't use 'export'. It isn't that much of a loss, anyways - the code requires recompilation for any type and the header should be included only where needed one way or the other, so why bother?
I just recalled that you could use explicit instantiation if you only need the template for some predefined types and need a speedup in build times (works good for testing with a handful of types).
try
1
2
3
g++ Main.cpp -o main.o
g++ ChainedList.cpp -o chainedlist.o
g++ -o a.out chainedlist.o main.o 



/tmp/cckuMyrX.o: In function `main':
Main.cpp:(.text+0x1a9): undefined reference to `ChainedList<int>::ChainedList()'
Main.cpp:(.text+0x202): undefined reference to `ChainedList<int>::insertAfter(Node<int>&)'
Main.cpp:(.text+0x25e): undefined reference to `ChainedList<int>::insertAfter(Node<int>&, Node<int>&)'
Main.cpp:(.text+0x2cf): undefined reference to `ChainedList<int>::getNode(int)'
collect2: ld returned 1 exit status


g++ is compiling fine, but it's not linking correctly.
Last edited on
ChainedList is a template class. It seems to be declared in a header and implemented in a compilation unit. Unless your compiler supports the "export"-keyword (which it doesn't) you have to provide the implementation in the header.


You should never have the implementation of any class in the header.
You should never have the implementation of any class in the header.


Unless you have a template class. Quoted from the tutorials:

When projects grow it is usual to split the code of a program in different source code files. In these cases, the interface and implementation are generally separated. Taking a library of functions as example, the interface generally consists of declarations of the prototypes of all the functions that can be called. These are generally declared in a "header file" with a .h extension, and the implementation (the definition of these functions) is in an independent file with c++ code.

Because templates are compiled when required, this forces a restriction for multi-file projects: the implementation (definition) of a template class or function must be in the same file as its declaration. That means that we cannot separate the interface in a separate header file, and that we must include both interface and implementation in any file that uses the templates.
You should never have the implementation of any class in the header.

Enlighten me, then. While I wouldn't take a tutorial as the "ultimate" reference, the authors of "C++ Templates. The Complete Guide" made a pretty competent impression on me. Quoting them: "Usually, you should use the inclusion model (that is, put all template code in header files".

1
2
3
g++ Main.cpp -o main.o
g++ ChainedList.cpp -o chainedlist.o
g++ -o a.out chainedlist.o main.o 

Er, you have about no idea how template code is handeled by most (in this case, especially g++) compilers, do you? How would the compiler be able to translate "ChainedList" without knowing which type it is to be used with? Consider
1
2
3
4
template <typename T> class C
{
  T t;
};

^^how large is t? Not an easy question, if you put yourself in the place of the compiler. The code simply /has/ to be known on the instantiation side *at compile time* (with C++98 and C++02 anyways, C++0x will have some neat new features). Even the "export"-keyword would most likely do exactly what you do including the template code, youst behind your eyes.
Hmmm.. Exception and Zhuge are correct. :) (I tested this on GCC 3.9.5)

This does seem very wrong to me, especially on a larger project. The idea behind Declaration/Implementation is to seperate them from each other for practical reasons (multi-definition, linking errors, cyclic-depencys) and maintainability. It's much easier for a 3rd-party developer to maintain code that is consistently laid out. Having it like this breaks consistency =\

That being said, I haven't created a template class in my own professional code for almost 5yrs. They are extremely handy for things like vectors/maps (the STL) etc, but I have seen very limited use of them otherwise. Most problems that could be solved by using a template usually will be solved by extending your OO model.
Looking at it otherwise, most of your OO problems can be solved in an quite elegant and often faster way using generic programming... Consider a function
1
2
3
4
void draw(drawable* d)
{
  d->draw()
}

with the usual example of circle, rectangle etc. inheriting from drawable. Now consider
1
2
3
4
template <typename drawable>void draw<drawable* d>
{
  d->draw();
}

The second solution clearly lacks support for runtime polymorphy, but often this is not a problem (indeed, more often than I expected when I first considered using compile time polymorphy). And when it is applicable it is much more generic then the first version - no inheritance from a special base is required, not *all* abstract functions have to be implemented if only a subset is actually required, error-prone multiple-inheritance simply is substituted by providing the interface for several concepts, ... In short, you can provide something that behaves like a drawable and you are done. Looked at it that way, I find that generic programming often provides a solution that is, for my purposes, better than OO programming (though you indeed have to use some "hacks" to make it work as it should in some instances - like the explicit instantiation for faster compilation).

BTW, with templates-in-headers you get as little problems with the ODR as you get with inline functions.

Another thing with "larger projects" is, in my opinion, that people have conservative concepts about sourcecode layout rules and regulations, file length, documentation, code management and alike. When my supervisor heared that a project of mine was contained in a single 20000+ lines file, he... was not very pleased. When he saw the neat literate program it represented (espectially it's superb documentation coming along with literate programming) and the fact that "conservative" 100-800 LOC files can be extracted from it automagically, this conception changed rapidly. My point is, code should be arranged in a way that humans can deal with it easily. The computer will handle somehow (and if one masters the used tools, it will do the job pretty well). And from the human point of view, header/source file splitting is in most cases far from intuitive, especially when trying to enforce the "usual" way when it is clearly misplaced (as with template code).
Looking at it otherwise, most of your OO problems can be solved in an quite elegant and often faster way using generic programming... Consider a function


That comes down to your methodology. I am, and am employed as an OO C++ developer. Therefore my code is always OO and I do not mix with a procedural methodology. It's important to pick 1 methodology and stick to it.

You shouldn't mix OO and Procedural programming in a single application, that's adding unnecessary complications.

Another thing with "larger projects" is, in my opinion, that people have conservative concepts about sourcecode layout rules and regulations, file length, documentation, code management and alike.


Yes, and for good reason. These projects often cost millions of dollars to develop and the companies have a lot vested in the success of them. They don't want to incur 10-20% overhead just because the developers didn't use a source-control system. It's about future-proofing your work so that it can be maintained by other developers.

When my supervisor heared that a project of mine was contained in a single 20000+ lines file, he... was not very pleased.


I would've very quickly asked you to refactor your code according to a common methodology. That's a sign of poor design and implementation.

When he saw the neat literate program it represented (espectially it's superb documentation coming along with literate programming) and the fact that "conservative" 100-800 LOC files can be extracted from it automagically, this conception changed rapidly.


I would question his knowledge of software development and how hard it would be for another developer to pickup this code and maintain it. If you were to leave, or something happened to you a single file with 20k LOC is going to be extremely difficult to maintain.

Sure it maybe easy FOR YOU to pull out snippets of code etc, but if you were killed then your employer has to get another developer in who'd have to spend weeks just coming to grips with a single file. As opposed to, coming in and having something named and filed in a common way that is easy to pickup and work with.

I sure as hell would not expect a developer to have to wade through a 20K LOC file just to fix a bug. Especially when bugs are usually a 1 line fix. Very poor planning IMO. You have unnecessarily added complexity and a level of un-maintainability to your application.

There is a lot more to programming than just writing nice code that you can maintain and pull pieces out. I have developed complex applications for other companies that I am no longer working for. They have successfully being able to bring in other developers who can maintain the applications very easily.

I now have employment references that can say I have worked on multi million $ projects and have provided them with good maintainable code. And in one case, with clinical information the code is easily able to be audited by other developers (as important when dealing with peoples clinical data .. and potentially information that could save/kill them).
I am, and am employed as an OO C++ developer.

Yes, well, I didn't mean to say that OO is bad or something. But I think that when working with a language that supports feature X one should consider using it. With the goto-statement, this consideration was rather short in my case, as was the consideration of using C compatibility (except for compatibility with already available C code). Everyone can pick the subset he likes, if the company allows it. And if it doesn't, well, you either are OK with that or you look for another job.

Sure it maybe easy FOR YOU to pull out snippets of code etc

Well, I expect my fellow developers to be able to type "make source" in a command prompt... after that, it is a fully GNU coding standard compliant project (which is OK regarding the company policy).

I would question his knowledge of software development and how hard it would be for another developer to pickup this code and maintain it.

No offense, but I'd guess that you have never seen a literate program. I want to invite you to have a look at Knuth's book about TeX, which is a literate program - yes, the whole book. And TeX is compiled from the same source as the book. Think about it: when you change "a bit" in your code, do you *always* change *all* the documentation? I certainly don't know anybody who does, *except* for people using literate programming. In my language there is a saying: "A picture says more than 1000 words". When have you last commented your code with a picture about what is going on? Well, with literate programming that is quite common.

I sure as hell would not expect a developer to have to wade through a 20K LOC file just to fix a bug.

Of course, my code is 100% Bug Free. No, seriously, you don't go through the source file directly (well, I wouldn't), you read the documentation (which happens to contain all the source code). You read what is the intention (which is documented), you read what has already been tried (which is also documented) and you proof-read the code, which is presented in neat, human-readable terms (since in the phase of development, it is clear to the developer that the code *will* be read by humans - so variable names like i, m, tmp, iter and other non-speaking names are absolutely off-limits)

You have unnecessarily added complexity and a level of un-maintainability to your application.

I'm actually adding the extra level of abstraction, which is the solution for many problems in computer science.

You might think (and say) that it is stupid to use templates and/or literate programming, and I respect your point of view, as much as I respect people who prefer C over C++, no matter for what purpose. But before doing either, I would very much like if you had a look at the possibilities of each (otherwise, this discussion is pretty much pointless). At first, I was sceptical about both. And indeed it took some time before I could use these techniques properly. But now that I can I would not want to abandon them. If you are interested in learning something about LP, you might want to have a look at
http://www.literateprogramming.com
Yes, well, I didn't mean to say that OO is bad or something.


That depends on who is using it :P

But I think that when working with a language that supports feature X one should consider using it.


This is really a moot point. Just because it's there, doesn't mean you should use it. A classic example would be strcpy(). A simple function with a simple purpose, but unfortunately it's use opens up possibilities of many bugs and exploitable code. The same goes with printf(). (C functions I know, but still used by many).

You should assess each feature of the language and decide if it's use is applicable, or a best practice. One of the problems with C++ is that it was directly built on C, and unfortunately inherited alot of the problems with C and bought through a whole bunch of it's own. C++ is one of the hardest languages to write stable and robust code because everything can be 100+ different ways and 99 of them will have potential flaws.

Everyone can pick the subset he likes, if the company allows it. And if it doesn't, well, you either are OK with that or you look for another job.


It's more than just this. Any half-decent company with Software Developers should have a formal standard of what methodology, coding style etc to use. They should have enough interest in protecting their own investments to do this, if not, then they are at fault.

No offense, but I'd guess that you have never seen a literate program.


You are correct. I have read through the page you supplied, and I cannot see any great merit in recommended this as a practice. For small programs with complex tasks I can see some very good uses for this.

But for large programs, or multi-developer teams, I would see this as an obstacle to development. You 1 file application would be an example of this, it'd be very impractical to have more than just yourself working on it.

Think about it: when you change "a bit" in your code, do you *always* change *all* the documentation? I certainly don't know anybody who does, *except* for people using literate programming. In my language there is a saying: "A picture says more than 1000 words".


I do not change "All" documentation. But I do change the high level design documentation if it's warranted. The code is always commented with a "this is what is happening" approach, why the code is the actual "how this is happening".

When have you last commented your code with a picture about what is going on? Well, with literate programming that is quite common.


There should be no need. High level design documentation should have "pictures" (UML, CASE etc diagrams) depicting how the application will function from an abstract point of view. Source code documentation should outline what is happening at various points in the source code.

Of course, my code is 100% Bug Free.


I can 100% guarantee that your code is not 100% Bug Free. Even with Literate Programming there are going to be issues your not aware of with functions or objects you have no implemented. E.g Buffer Overflow, Format String Bugs etc.

No, seriously, you don't go through the source file directly (well, I wouldn't), you read the documentation (which happens to contain all the source code). You read what is the intention (which is documented), you read what has already been tried (which is also documented) and you proof-read the code, which is presented in neat, human-readable terms (since in the phase of development, it is clear to the developer that the code *will* be read by humans - so variable names like i, m, tmp, iter and other non-speaking names are absolutely off-limits)


If all of this is in a single file, then I would imagine that it'd be hard to follow the path of execution through large amounts of code quickly (as a developer). This would make it difficult to truely proof-read the code because it'd be difficult to get an understand of "how" it's doing things, as opposed to "what" it's doing.

I'm actually adding the extra level of abstraction, which is the solution for many problems in computer science.


Unfortunately, what is taught in CompSci is very different to the real world. Looking at requests for homework etc on this forum is very much evidence of this. CompSci has always had a very real focus on algorithm design and abstraction, yes. But these are not always practical solutions when in the real world designing and developing real world applications.

You might think (and say) that it is stupid to use templates and/or literate programming,


I think template programming is a personal preference thing. It's taught poorly in universities unfortunately and people tend to rely on it to solve problems without looking at the design of their application first.

Literate programming, as described by the web-site, and shown by your work to me is definitely not a scalable real-world development methodology. While it may have worked well for your 1-developer project. I could never see this being a practical methodology for a 20+ person development team.

And indeed it took some time before I could use these techniques properly. But now that I can I would not want to abandon them.


What scale of development have you worked on? I am interested to know the size of projects and development team size you have worked on? Also the application domain? (retail apps? science apps? data keeping apps?)

as much as I respect people who prefer C over C++, no matter for what purpose


C and C++ are different languages. There are real reasons to use C over C++ (e.g Embedded Programming, low level driver development). Unfortunately, most of the favor for C now stems from problems in C++'s abstraction that makes things "unknown" to the developer.


I do welcome a good discussion, especially about development methodologies. I did find 2 good quotes though

- "The relevance of literate programming has been reduced a bit by features such as syntax highlighting in later programming environments." (Later environments? :P)

- " Many students object that the ideas of literate programming are academic, in the meaning of being speculative without a practical purpose or intention. The scepticism seems to be justified by the fact that very little practical program developement is done 'in the literal way'."
Just because it's there, doesn't mean you should use it.

No, but I didn't say that. I said that it should be /considered/, just like you say:
You should assess each feature of the language and decide if it's use is applicable, or a best practice

(Er, might be that my understanding of "consider" is not completely what it really means. My dictionary tells me that I used it when I should have used "assess"...)

High level design documentation should have "pictures" (UML, CASE etc diagrams)

These are diagrams showing the structure of the code. They don't show algorithmic aproaches, data visualizations from program tests and alike.


It's more than just this. Any half-decent company with Software Developers should have a formal standard of what methodology, coding style etc to use.

In the case of literate programing, (at least with noweb, the program I use) the code generated by "make source" /can/ be 100% compliant with any company policy. It wolud be rather stupid to write "usual" comments in a literate program, giving up all the formating power (formulas etc.), but then again it is possible to extract the tex documentation chunks as comments (would take a script, I didn't need that until now...).

For small programs with complex tasks I can see some very good uses for this.

Thats how it started for me....

But for large programs, or multi-developer teams, I would see this as an obstacle to development. You 1 file application would be an example of this, it'd be very impractical to have more than just yourself working on it.
[...]
Literate programming, as described by the web-site, and shown by your work to me is definitely not a scalable real-world development methodology. While it may have worked well for your 1-developer project. I could never see this being a practical methodology for a 20+ person development team.

20+ persons might be difficult, I agree. But that would depend on the organization and architecture. I have learned that not using a signle file is more of a "conservative concept", something one is /used to/, but not really because it is the only feasable approach. The whole concept of files has flaws, I think: how do you sort your music collection (if not on a computer, in form of CDs, which I would then view as files)? After composer, interpret, genre, mood, ...? No matter how, it is sorted the wrong way when you look for something special. And when you use a database which manages the tags of individual files, how large should the files be? One symphony? Or one movement? 1:30 minute pieces? You remember how something was like, but not the names you have to look for.
These problems cannot be solved by putting all files into one, that's correct. But having files as an "orientation guide" is not as intuitive and useful as often assumed. And working in one file on source code, searching for something using regex has become much more useful for me thang going over several files, looking through all (and on team projects, where I have to, I use grep to do it - thats a 'Esc !grep <regex> ../include/* -R intead of '/<regex>', which is OK but certainly not "better" - and yes, you may declare me completely crazy for using VIM instead of an IDE).
Another example here is the .cpp/h splitting. Surely you know the Pimpl Idiom. Problem: the declaration of private members is not in the header where you would expect it. With noweb, I write (code chunks only, no documentation...):
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<<class declaration>>=
class C
{
    struct impl;
<<class impl data members>>=
  int* a;
  int* b;
<<class declaration>>=
    std::auto_ptr<impl> pimpl_;
  public:
    ...
};
...
<<classes impl>>=
struct C::impl
{
  <<class impl data members>>
  ...
};
@

Now, the members are extracted to the right code file for the compiler, but are listed were they belong - to the class that uses the impl. (You might consider the Pimpl Idiom "not good" for this reason or whatever else, please don't bother about this special case, think about cases in your code where this extra abstraction yields in more "locality for the reader" - where the reader can be the implementor, library user, maintainer, ... Note that not only source code, but also configuration files, testing scenarios etc. can be contained in this form right were they are applied.

What scale of development have you worked on?

I get an engine which I have to use, and I can complain about it but that doesn't change anything, so I count the development team for the engine out (and any component developed similarly)... after that, the team size is ~5-8 developer, so quite small. Furthermore, until now only two of us were using literate programming. Noone else ever noticed, until my superviser onece dropped by when I did some implementation... Working with 2 people on one file is quite different from 20+, yes. But I'm pretty sure that much of it would scale, and that the rest could be re-designed to become scalable (I wouldn't have said that and been pretty sceptical if heared that about 2 years ago, so I understand if you say "grow up and work in a real team...").
I think that it would scale because it the extra abstraction allows for new ways to split the code: one can write high level blocks, like
<<merge sort>>=
<<split data if not sorted>>
<<merge now sorted data>>
@
the other one can implement the low-level blocks. CVS will notice that no confilcts are present... Or, one can write the chapter "Data Structures Supporting Ranges", the other one the chaprer "Algorithms on Ranges". The chapters are physically seperated, so a CVS merge does it all.

I can 100% guarantee that your code is not 100% Bug Free

But you *did* get that it was ment as a joke, didn't you
Last edited on
Errr... Aside from the fact your using CVS, which is unfortunately losing alot of market-share because of missing features that are considered a "requirement" by many Snr Developers nowadays (atomic commits etc).

I get an engine which I have to use,


Ahh yes. I have seen these sorts of implementations before. I was offered a job to work for a company that had developed it's own programming language, IDE and WYSIWYG editor. But I didn't want to be limited to a specific framework for development.

And working in one file on source code, searching for something using regex has become much more useful for me thang going over several files, looking through all. Another example here is the .cpp/h splitting


Then your tools are lacking, and your methodology is compensating for this. I can control+click on any function and I'll be taken to the implementation or declaration.

My current project is 20K LOC (so, quite small) and it's in approx 200 files. However, it's multi-platform and multi-threaded.

Is it easy to follow? Yes, because I have a non-developer who has to make code-changes to it. Add new classes, make configuration changes etc. Non-developers can easily follow the high level documentation that details the design philosophy and make easy changes to the application, as well as adding new Unit Tests (also in a hierarchical OO structure).

Is it flexible? Yes, because it's runtime behaviour is completely defined by user configuration files. With an empty configuration file, nothing will happen. But with a well written configuration file it's capable of modelling a complex spatial abundance environment.

I have no template classes, because the design methodology allows me to overcome the need for them with a robust Parent-Child Hierarchy. Objects are polymorph'd at runtime continuously. Nothing against templates, but the code is much easier to read without everything being templated.


Working with 2 people on one file is quite different from 20+, yes. But I'm pretty sure that much of it would scale, and that the rest could be re-designed to become scalable (I wouldn't have said that and been pretty sceptical if heared that about 2 years ago, so I understand if you say "grow up and work in a real team...").


I think you will find, that as the team grows using a methodology like literate programming doesn't scale and incurs greater overhead. Looking around articles about Literate Programming (as I have been today) you can quickly see why the concept has not become mainstream (when something like Agile has). Especially when your application hits >100k LOC and has a n-tier architecture.

Having skills in literate programming is not a "transferable" skill in modern software development. You will find it hard (if not impossible) to find further employment utilising that skillset. The other downside is that, people become too reliant on the engine and when they do end up in a new company their knowledge of the base language and concepts is fundamentally lacking (and I have dealt with developers in that exact situation).

I also question the validity's of having a "novel" for code, which yes is very human readable, but in reality the target audience will almost always be maintenance developers. Who should be more interested in the code than the algorithms. As these should be functioning when the application is implemented into a production/live environment.

Your literate programming implementation seems very reliant on algorithm design and implementation. Would this be a correct assumption? I would question why a language like R or S+ is not used instead?

I could never see this working in a large software development team. Larger teams often ramp numbers up or down quickly with external contractors. Having a standard OO/Agile approach is easy for external developers to come in and work on the code. Having the overhead of doing literate programming is going to cost the company millions$ in just getting people up-to speed.

I'd be happy for another developer to chime in and give feedback either pro/con Literate Programming. But I personally would rate it's usefulness on par with FORTRAN (and ironically, where I work we have a super-computer that runs FORTRAN applications.. so there is a very niche use).

It's interesting having this discussion. As I am going through designing a software development team as part of a restructure. And being a national organisation with campuses across the country it's been important to look at available methodologies and technologies and cross-compare these with what is available in the current work-force. There is no practical way we could consider something like literate programming, as it's not taught, not practiced enough to make it a viable choice. Ironically, even C++ isn't really even a viable language for most of the development.

Edit: This is a completely standard guide to writing code that I would expect to be acceptable in 90%+ of Companies. The other 10% would deviate slightly.

http://google-styleguide.googlecode.com/svn/trunk/cppguide.xml
Last edited on
Then your tools are lacking, and your methodology is compensating for this.

I agree, but I would rephrase: "My tools and my methology are going hand in hand. Changing one without the other would be futile."
Look at where digital photography has taken us: worse pictures, mainly. Not because of some lacking megapixel, but simply because people don't think much before taking a picture. With analog pictures, taking one did cost money (be it negligibly little compared to the other equipment), so people have taken their time to think before they shot. Now, "you can take as may pictures as you want" - well, not true, after the first one the moment is gone.
I think the same is true with software development. I guess that if one were to make a study one would find that people knowing the code they work with by heart are more productive than developers depending on auto completion, "Ctrl+Right Click" and alike. (Of course, this is not applicable for maintenance, where I prefer an IDE with these features, too.) The tool is not to blame, but I think the way people use it simply is not the "best way".

you can quickly see why the concept [LP] has not become mainstream

I can the *that*, but not *why*. I don't consider "that" to be a valid argument against LP. I'm sure you can think of something you consider a Good Thing which didn't come widespread.

I think you will find, that as the team grows using a methodology like literate programming doesn't scale and incurs greater overhead.

That might be. But as a scientist, I'd have to try and prove, for the answer is not obvious to me.

Having skills in literate programming is not a "transferable" skill in modern software development

Waitaminute. You didn't even try it... how do you know what skills are involved? For me, one of the most demanding tasks in LP has been to find good names (for variables, functions, classes, ...) - in a way far beyond guidelines, I consider that a *very* important aspect (try to understand any well-known algorithm in a forign language to understand what I mean. Then imagine a not-so-well known...).

The other downside is that, people become too reliant on the engine and when they do end up in a new company their knowledge of the base language and concepts is fundamentally lacking (and I have dealt with developers in that exact situation).

That might have been a misunderstanding. It's a 3D engine which is "Company-Brew", but the development team is completely seperated from the teams I've worked in. For me it is an API to use, nothing more. And *my* code could be made work with any other engine supporting a similar functionality within a matter of hours.

Your literate programming implementation seems very reliant on algorithm design and implementation.

LP in my understanding tries to take the focus from implementation details to algorithms, if that's what you mean (on the other hand, I seem to be the only person in my company who knows anything about exception safety (and writes exception safe code), something many people would consider an "implementation detail". But the LP abstraction allows for a neat separation of actual functionality and error handling, what took me there in the first place). The code I work on is scientific/research related, so having error handling in the functionality would distract from the actual work. I don't see a downside here, but perhaps I just don't understand what you are saying.
Why C++? The code uses facilities written in C and is partly high-performance code, executed on Tesla servers (real-time raytracing etc.). Furthermore, for any code with a mathematical component, operator overloading is a requirement, and so are templates (for us...).

Larger teams often ramp numbers up or down quickly with external contractors

I think that is quite different where I live in general than it is in the USA. Here, things are "slower", which can be a disadvantage, but I also see advantages. But that's another topic. Long story short, that's not an issue here.

I have no template classes

Don't you ever input or output ranges from/to arbitraty containers? Wow, I'd be screwed without them... waitaminute, that only requires template functions. Don't you ever require a new container type which works with the stl algorithms?

I've browsed throught the style, and except for
Use [...] NULL for pointers

my code is compatible (as far as I can tell ad hoc, of course not deliberately following all the guidelines leaves room for some incompatibilities, but they could be fixed in a day or two). BTW, I discourage anyone from using the NULL macro (but that's not the point here, I guess)

To summarize: I see advantages and disadvantages, just as I do with any paradigm. In general, it allows to be compliant with any policy, so it can be used in the code one is responsible for. And even though I perhaps won't use it in my whole life, I am pretty happy that I've learned what I did from it. But usage might be (that would have to be tested) restricted and is intended for scientific applications, not large companies.
I think the same is true with software development. I guess that if one were to make a study one would find that people knowing the code they work with by heart are more productive than developers depending on auto completion, "Ctrl+Right Click" and alike.


Look back at code you wrote 12 months ago. Anything remotely complex you will most like not understand, and then you start to rely on the tools to help you re-learn code. I do this frequently with 3D OpenGL/Engine code when I need snippets for other applications.

I can the *that*, but not *why*. I don't consider "that" to be a valid argument against LP. I'm sure you can think of something you consider a Good Thing which didn't come widespread.


Sure, Beta should've been mainstream over VHS. But they were beaten by marketing and distribution deals.


LP in my understanding tries to take the focus from implementation details to algorithms, if that's what you mean .... The code I work on is scientific/research related, so having error handling in the functionality would distract from the actual work. I don't see a downside here, but perhaps I just don't understand what you are saying.


Exactly what I was thinking. LP does seem suitable to writing code as a scientist (and I work with scientists who write code). But from a software development point of view, the algorithm is less important than the application design.

I think that is quite different where I live in general than it is in the USA. Here, things are "slower", which can be a disadvantage, but I also see advantages. But that's another topic. Long story short, that's not an issue here.


I think you will find many industries still hire large amounts of contractors when ramping up projects to meat deadlines.

Don't you ever input or output ranges from/to arbitraty containers? Wow, I'd be screwed without them... waitaminute, that only requires template functions. Don't you ever require a new container type which works with the stl algorithms?


Nope. By having sound hierarchical structures I can avoid the need for templated code. Everything in my code follows guidelines that relate to the OO structure. Polymorphism is a very powerful tool. Sure, I use STL containers, but I don't write my own, inherit from them or have my own templated classes.

But usage might be (that would have to be tested) restricted and is intended for scientific applications, not large companies.


I think this is an important observation, and something I'd likely agree with. Especially working as a software developer in a scientific organization. But I don't think it'd be much use in other industries. Even in a scientific organization I think it's use would be limited to scientific programming, as opposed to enterprise development.

I'd hate to see an J2EE application developed in LP. They are nasty by themselves :P
Last edited on
from a software development point of view, the algorithm is less important than the application design.

I find this observation interesting. How much "less" important would you consider it, and abuot what exactly are we talking here? Is it rather the fact that less "algorithmic research" is done (i.e., you most likely won't come up with a completely new sorting algorithm), or is it less interest in algorithms alltogether ("merge sort? quick sort? I know what the result is, I can code them, but I don't care why they do exactly what they do..."), or do you mean something entirely else?
Because that's what it boils down to, in my opinion: for a new algorithm I consider LP to be a Good Thing. For the STL, I'm pretty happy with the standard and a neat requirements/concepts overview in a book (I would, as an implementor, still use LP to contain/generate these documents, but I don't consider it a great loss not to have a LP version of it. On the other hand, the standard *is* a LP version of the STL declarations - all that's missing is a tool to extact the code...)
I will give my current project as an example, as you should be able to relate to it and what I mean by that statement.

I am writing a spatial population model (first of it's kind) for a scientific project. I am not a scientist, I am an OO developer. Therefore, my approach has been from an OO point of view to developer robust, scalable and reliable software. I have knowledge of how the objects work together, the relationships they must have etc, but I have little knowledge of the actual algorithms in use.

The actual algorithms are a matter for the scientist involved. It's his job to come up with these, I am merely providing him with a suitable framework from which to test his theories.

So, From a software developer point of view. The algorithm is not as important as application design.

There is a non-spatial population model developed by this company. It was done so by scientist's who program (very different to a software developer). Unfortunately, the code is pretty much unmaintainable because they have no use proper design and development methodologies and have instead concentrated on the algorithms involved.

Back to my project. This approach has been so successful, that it's been looked at by international science organisations as a way to model other things we had never considered. The framework is the perfect sub-system for them to test their algorithms on.
Pages: 12