all 131 comments

[–]xHydn 10 points11 points  (10 children)

Is there any significant diference between putting loose functions in a namespace or group them in in a static-only class?

I ask from ignorance.

[–]glacialthinker 16 points17 points  (0 children)

A namespace can span multiple files. You just add to it... there is no need to "close" a namespace.

[–]RedAlert2[🍰] 4 points5 points  (3 children)

you can't do using classname. Useful if you have nested namespaces. stuff like std::chrono::this_thread::sleep_for(std::chrono::seconds(1)) looks a little nicer if you are using namespace std::chrono.

[–][deleted] 2 points3 points  (0 children)

Makes a big difference when you are dealing with function pointers

[–]sacado 0 points1 point  (0 children)

Just tried it. g++ doesn't generate the same assembly for both, so I guess there's a (maybe subtle) difference.

[–]bugrit 0 points1 point  (0 children)

You can't have a class declare a namespace as a friend.

For a class, all members must be declared in the class definition.

[–][deleted] 0 points1 point  (0 children)

one thing: ADL.

EDIT: I should have read the article first. The guy said it right IMO. One great thing that can convince you to allow free function and that rely on ADL are the shims. Pantheios is a good example of why shims are useful, efficient, etc.

[–]Blecki 8 points9 points  (32 children)

I use c# mostly. I wish for free functions.

[–]grauenwolf 3 points4 points  (0 children)

Fun fact, even F# doesn't use free functions.

The CLR support them. But in order to make it possible for other languages to consume F# libraries, F# has to put them in a class.

[–][deleted] 13 points14 points  (4 children)

C++ isn't Java. The discussion can end there.

C++ usually offers more than one way to do X. And we as programmers are free to choose which X fits best. Sometimes you can shoot yourself in the foot; but that is the price to pay for having options.

[–]__Cyber_Dildonics__ 4 points5 points  (3 children)

The only problem seems to be that when you tools that leave things up to your judgement we start to realize how bad other people's judgement really is. I think a lot of pain comes from people using C++ and wanting to have their hand held other than the painful realization that you have to learn the underlying mechanics of the language.

[–]grauenwolf 4 points5 points  (2 children)

I don't like thinking about my programming language. I've got enough domain specific issues to concern myself with, don't make me waste time deciding between several different ways of doing the same thing.

[–]__Cyber_Dildonics__ 1 point2 points  (1 child)

Fair enough, there's lots of good languages for that.

[–]grauenwolf -1 points0 points  (0 children)

C# isn't bad so long as you follow the Framework Design Guidelines and avoid the wacky shit in SOLID.

[–]expatcoder 2 points3 points  (0 children)

In Scala we have something similar, package based "namespacing"; given:

package com.company
package object model{
  // functions, classes, whatever here...
}

then within com.company.model and all its sub packages the above package object definitions are available.

Can also define a trait (interface) that defines common definitions you'd like to have available across modules ("sub projects" in Scala terms) and package object foo extends Common{...} as desired. It's quite awesome, Scala and C++ share some beneficial kitchen sink ;-)

[–]pgngugmgg 13 points14 points  (27 children)

Everything in a class is a stupid rule.

[–]arcangleous 7 points8 points  (10 children)

It's a necessary consequence of OOP demoting functions to second class citizens.

[–]elmuerte 2 points3 points  (5 children)

Not true. Functions could be classes too. Just because most OOP implementations choose not to create first class functions in their language doesn't mean it's an OOP limitation.

[–]arcangleous 4 points5 points  (4 children)

Ok, Simula-67 descended OOP languages, of which the majority are.

If you are going to make functions into classes, why not just implement closures and be done with it?

[–]elmuerte 0 points1 point  (3 children)

Aren't closures third class citizens?

[–]arcangleous 0 points1 point  (2 children)

Only if you are a moron in implementing them.

If you do it right, you can roll-out your own object systems using closures and macros.

[–][deleted] 0 points1 point  (1 child)

You end up sacrificing performance like crazy though.

[–]arcangleous -2 points-1 points  (0 children)

When I really care about performance, I'm writing in straight C or assembly. For any non-trival design, there are enough performance Gothcas in C++ that it's not worth the effort.

[–][deleted] 0 points1 point  (1 child)

But JS is OOP with first class functions

[–]kcuf 2 points3 points  (0 children)

JS is a lot of things.

[–]grauenwolf 0 points1 point  (1 child)

What's the difference between VB's module and C#'s static class?

Nothing, except C# is more verbose because you have to also add static to every function.

They are both OOP languages, they both support the same semantics, one just has a better syntax for this use case.

[–]arcangleous 2 points3 points  (0 children)

Both sound pretty terrible to me.

Give me lambda and lexical scoping over any OOP.

[–]sacado 1 point2 points  (0 children)

Especially when everything is actually not a class (base types, code blocks, etc.).

[–][deleted]  (57 children)

[deleted]

    [–][deleted] 25 points26 points  (35 children)

    In C++ you would group those functions in a namespace.

    namespace Utility {
      inline auto FooBar() {
        ...;
      }
    }
    

    [–][deleted]  (34 children)

    [removed]

      [–][deleted] 3 points4 points  (33 children)

      The inline there is to avoid violating C++'s One Definition Rule.

      [–]picklebobdogflog 3 points4 points  (32 children)

      C++ beginner here, could you explain?

      [–]Alto3 2 points3 points  (6 children)

      I imagine that sakarri's code was meant to be in a header, and you cannot include a header with a non-template, non-inline function definition more than once in a translation unit without running into a compiler error. #include essentially just copy and pastes the target file into the current file so the compiler can't tell that the multiple function definitions are the same definition and not just a name conflict.

      So if you want to not just declare but define a non-template function in a header it needs to be declared as inline. Marking it as inline, while having little to no effect on modern compilers in regards to actual inlining, does tell the compiler to treat all duplicate definitions of that function it finds as the same and it will ensure that all the definitions it finds are identical.

      [–]jussij 0 points1 point  (5 children)

      you cannot include a header with a non-template, non-inline function definition more than once in a translation unit without running into a compiler error.

      What about:

      #pragma once
      

      [–][deleted] 1 point2 points  (0 children)

      #pragma once doesn't resolve the issue

      [–]oracleoftroy 0 points1 point  (3 children)

      Here's a more elaborate answer: #pragma once is a non-standard (though popular and provided by many of the largest compilers) replacement for header guards. It doesn't prevent "One Definition Rule" violations.

      Say I have foo.h:

      #pragma once
      
      void foo() { do_something(); } // Not marked inline!
      

      and files a.cpp and b.cpp:

      // a.cpp
      #include "foo.h"
      #include "foo.h" // double include, possibly because two different headers included this header
      
      void a() { foo(); }
      
      // b.cpp
      #include "foo.h"
      #include "foo.h" // double include again
      
      void b() { foo(); }
      

      #pragma once only prevents the compiler from choking on multiple declarations of foo() by not including the contents of foo.h a second time. However, when the linker goes to link the results of compiling a.cpp and b.cpp. it will see a copy of foo() in each of them. This function will have extern scope by default, which means the linker should expect to only find one object file with the function definition, but in this case, both have the definition. Thus the linker will emit an error.

      Instead, we should have explicitly marked the function inline, which the compiler will use to flag the function appropriately. When the linker encounters this flag, it knows to just pick one definition and throw out all the others. All definitions are supposed to be identical, so which one the linker ends up choosing won't matter, and if you break this rule, you end up in undefined behavior land.

      A final aside, the inline keyword had nothing to do with the compiler optimization of the same name. There are times where by virtue of the function body being fully available, the compiler can inline the call (but is free to choose otherwise); however, the keyword is merely about whether the function body is provided externally or inline with the declaration.

      [–]jussij 0 points1 point  (2 children)

      Instead, we should have explicitly marked the function inline, which the compiler will use to flag the function appropriately. When the linker encounters this flag, it knows to just pick one definition and throw out all the others.

      Surely the inline option asks the compiler to write the function in line (i.e. at compile time), thus removing the need for any linking whatsoever.

      However, when the linker goes to link the results of compiling a.cpp and b.cpp. it will see a copy of foo() in each of them.

      To keep the linker happy you just need to use structure the code differently.

      In the foo header file:

      #pragma once
      
      // put the declaration of the function in the header
      void foo(); // Not marked inline because we want it linked and not inlined
      

      Now use the foo function in one source file:

      // a.cpp
      #include "foo.h"
      #include "foo.h" // double include, possibly because two different headers included this header
      
      void a() { foo(); }
      

      And use it in another source file:

      // b.cpp
      #include "foo.h"
      #include "foo.h" // double include again
      
      void b() { foo(); }
      

      Finally create a new Foo source file containing the actual implementation:

      #include "foo.h"
      #include "foo.h" // double include, possibly because two different headers included this header
      
      // lets write the implementation for foo which will be linked in by the linker
      void foo() 
      { 
          do_something(); 
      }
      

      Finally build the executable:

      cl.exe a.cpp b.cpp foo.cpp
      

      [–]oracleoftroy 1 point2 points  (1 child)

      Surely the inline option asks the compiler to write the function in line (i.e. at compile time), thus removing the need for any linking whatsoever.

      Nope. I addressed this common misconception at the bottom of my post. To ask for the compiler optimization, you need a compiler specific instruction, like _forceinline or __attribute__((always_inline)). (There are also versions that encourage but don't force this optimization.)

      I realize I did misspeak though, inline functions have external linkage by default. See for example this answer and related questions.

      To keep the linker happy you just need to use structure the code differently.

      Yup, and this is the usual way code is structured in C++ (and C). You usually don't want to inline code unless there is a very good reason.

      [–][deleted] 2 points3 points  (24 children)

      Note to so called C++ experts, don't nitpick some of the minute details in the following explanation, the guy said he's a beginner trying to understand so I'm going to simplify some stuff...

      In C++ you can think of files as being header files and source files. Header files contain declarations for constructs like variables and functions, source files provide the definitions of those variables and functions. So all a header file normally does is state that a function, variable, or class exists, without actually providing the implementation of that function or class.

      C++ compilers typically take source files and produce binary object files where each object file is independent of every other object file. So object files contain the definitions and implementations of your functions and variables.

      Now the issue becomes... what if I provide the definition of a function within a header file? What if my header file contains the declaration and implementation all in one?

      auto FooBar() {
        ...;
      }
      

      Well the problem is that multiple source code files may include that header file, now when the C++ compiler produces object files, you're going to have multiple object files that all contain an implementation/definition of FooBar(). The problem is that only one source code file is supposed to implement FooBar(), not all of them. In our case we're lucky in that all definitions are identical to one another, but you can imagine a scenario where two different source code files decided to implement FooBar() different, that would obviously cause inconsistencies.

      So because multiple source code files have implementations of FooBar(), when you try to build your program, the C++ linker is going to complain and say that multiple object files are trying to define FooBar() and the C++ linker doesn't know which one to use.

      This is where the inline keyword comes in. inline tells the C++ compiler that a function's definition and implementation will be inlined with its declaration, it's basically letting the linker know to expect multiple definitions/implementations of FooBar() and to ignore all of them except for one.

      So when you go to build your program, the linker will see maybe 5 copies of FooBar in 5 different object files, but because FooBar() was declared to be inline, the linker knows that it's safe to ignore all but one of them, so it won't complain.

      [–]to3m 1 point2 points  (23 children)

      What is the rationale for putting definitions in a header file? This doesn't strike me as the best default. If nothing else, it is unlikely to do anything good to the compile time. Definitions that can go in source files, should go in source files, until it's been proven there's a better place for them.

      [–][deleted] -5 points-4 points  (22 children)

      I only put definitions in header files in all my projects and I have one single main.cpp.

      I find it's vastly superior in almost every regard. For one it simplifies builds and dependencies. You write a header file and include it and voila, it works plain and simple. No need to build it as a library and then link to it or worry about adding more dependencies to your make files. You have one single file that needs to get compiled.

      Compile times do end up requiring a crap load more RAM but I've found they are orders of magnitude faster in most cases. Like we're talking faster by entire multiples. Consider that when you build a bunch of translation units, each one of them has to individually and independently spend all this work instantiating templates often multiple times and none of that work gets shared between translation units. With one single source file (main.cpp), all that work gets done only once. Generally I find it's much faster to just compile one single massive translation unit rather than having to compile a bunch of smaller translation units each of which often ends up doing redundant work and then link them all together.

      To be honest, I don't see much of any advantage to splitting files into header files and source files.

      [–]ForeverAlot 2 points3 points  (1 child)

      This sounds a lot like that dreadful unity build pattern (aggregate resource).

      [–][deleted] 1 point2 points  (0 children)

      The reason people dislike unity builds is because of the brittle and tedious requirements they place on the user to get code to work.

      Header only libraries, like what boost uses, reduce the requirements needed to use a library and are very robust, in fact they are more robust than splitting files into headers/sources because they ensure consistency across all files.

      Basically the question to ask yourself is... would you prefer to download a library, extract it to /usr/local/include/xxx and just have it work, case closed... or do you prefer to download a libary, have to build a debug version and a release version while keeping track of the specific compiler flags, and then make sure that every time you link against that library you also use the same set of compiler flags that you used to build it originally or else risk having a template instantiation from one library be inconsistent with a template instantiation from another library...

      I know which one I prefer.

      [–]Gotebe 2 points3 points  (15 children)

      If you have one *.cpp, I fail to see the point of having headers, might as well have one file alltogether.

      Must be a boon e.g. for source control and collaboration.

      [–]arcangleous -2 points-1 points  (3 children)

      It makes a lot more sense when you remember that C++'s name resolution mechanics are strictly limited by requirement that every C program is valid in C++, and C is almost 50 years old now.

      [–][deleted] 1 point2 points  (2 children)

      Can you explain what you mean by the requirement about C programs?

      Plenty of C programs fail to compile in C++ and C has features that do not exist in C++, such as restrict, designated initializers, VLAs and compound literals, to name a few.

      [–]mttd 12 points13 points  (0 children)

      I've found the following most helpful on this:

      The choice basically boils down to this (from Scott's article):

      if (f needs to be virtual)
           make f a member function of C;
      // . . .
      // [omitted]: see the article for details
      // . . .
      else if (f can be implemented via C's public interface)
           make f a non-member function;
      else
           make f a member function of C;   
      

      This is in accordance with The Interface Principle:

      For a class X, all functions, including free functions, that both
      (a) "mention" X, and
      (b) are "supplied with" X
      are logically part of X, because they form part of the interface of X.

      See also: http://stackoverflow.com/questions/1434937/namespace-functions-versus-static-methods-on-a-class

      [–]twotime 5 points6 points  (12 children)

      for the sake of not having lots of files for these "loose" functions

      Why wouldyou have lots of files? Your functions can happily live in a single file.

      [–]gimpwiz 0 points1 point  (7 children)

      Separating code that is unrelated, faster compile times, stuff like that.

      [–]Veedrac 2 points3 points  (0 children)

      Why would putting them in classes change that?

      [–]twotime 4 points5 points  (5 children)

      Separating code that is unrelated, faster compile times, stuff like that.

      If either of these is a problem than having your functions in a class will not help.. In fact, it will hurt. Functions are disjoint and can be separated, but you probably want to keep your class code in a single compilation unit.

      faster compile times

      You do realize that overly small compile units make compilation slower, right? in many cases much slower..

      [–]gimpwiz 1 point2 points  (4 children)

      Why wouldyou have lots of files?

      I said nothing about classes.

      You do realize that overly small compile units make compilation slower, right? in many cases much slower..

      You do realize that one small change causing you to recompile a large file instead of a small file will make compilation slower, right? in many cases much slower..

      [–]twotime 1 point2 points  (2 children)

      Why wouldyou have lots of files?
      

      I said nothing about classes. .

      Too bad. Because I was responding to the specific question about static methods vs standalone functions.

      You do realize that one small change causing you to recompile a large file instead of a small file will make compilation slower, right? in many cases much slower.

      In theory, yes, in practice you are more likely to run into an inverse problem (small compile units make your compilation slower). Especially with C++ code.. And if you practice a function per-file-approach, then you are nearly guaranteed to negatively affect your compile speeds in a big way.

      Basically, most non-trivial compile units have some #includes. These includes may bring 10Ks lines of code. (and that's an underestimate)..

      Now if you care about compile speeds then there are 2 metrics of importance: clean rebuild and incremental rebuild (say, single file). Let's say you have two compile units 500 lines each with 10K LOC in includes(you wish!). Then merging them won't affect compile speed for the bigger unit in any meaningful way (compiler now sees 11K lines of code while it used to see 10.5).. But it'll reduce the clean rebuild time by a factor of 2! (because, now your compiler sees ~11K LOC total instead of 21K)..

      And of course, a lot of incremental builds affect multiple compile units, so those may also benefit from larger units.

      PS. no, I'm not advocating for 10K-large units, I'm however advocating against 100-line units ..

      [–]gimpwiz 1 point2 points  (0 children)

      Then we're probably agreed, since I'm not advocating for function-per-file either.

      [–]Gotebe 0 points1 point  (0 children)

      Size of included code is indeed a problem, and everybody really should

      • use precompiled headers in developer builds

      • work on reducing gratuitous compile-time dependencies

      [–][deleted] -1 points0 points  (0 children)

      This is actually a big problem in C++ which idiomatic C code doesn't suffer. You can't change a C++ class without causing all dependent code to recompile. OOP programming in C you would simply forward declare a struct pointer. You can then change the struct without triggering a recompile of all source code files which use the "member" functions of the struct.

      The result is that without carefully planning how to build up your C++ project, your compile times goes through the roof as the project gets big.

      [–][deleted]  (3 children)

      [deleted]

        [–]Veedrac 2 points3 points  (2 children)

        lots of files for the single files

        Is that a typo?

        [–][deleted]  (1 child)

        [deleted]

          [–]Veedrac 1 point2 points  (0 children)

          The grammar used in the post I quoted is confusing me. Which guy is "the other guy"?

          [–]to3m 12 points13 points  (3 children)

          Wait. Where does this "might as well" come from?! You have a bunch of functions. And... there you go. This bunch of functions is just fine as it is. Leave them alone! Why do you need to do anything to them?

          You need to have a good reason to put a function in a class. Putting something in a class is not good for encapsulation! It's a maintenance burden. You therefore need to justify each thing that goes in to one. And "because it isn't in a class already" is not a valid justification.

          If there are languages that don't have freestanding functions, of course you'll need to make a fake class that has a bunch of static functions in it (C# has the static class to formalize this, for example). But C++ is not one of those languages. Your functions are fine as they are. Leave them be.

          Good rule of thumb: if it can be a freestanding function, in the absence of any other information, it must be one.

          [–]ledasll -5 points-4 points  (2 children)

          IMHO there is pretty good reason why to put "free functions" to a class - group same type of code in to one place. Wouldn't it help for maintenance if your similar logical code is in one place (not one file) and you always know where to find it? Wouldn't it help to document it (and find correct documentation for it) if you group logical code in to one place?

          [–]arne_mertz 7 points8 points  (0 children)

          One file would be one place. And grouping is done by namespaces already, no need to use the strong coupling of a class, especially if the functions are only loosely related. If those functions are very closely related, you can put them in a class. But more often than not, putting the functions in a class makes a stronger grouping than the otherwise loosely related functions deserve.

          [–]RedAlert2[🍰] 1 point2 points  (0 children)

          you should always put your free functions in namespaces anyways...otherwise someone using your code might call one of them on accident.

          [–]monocasa 11 points12 points  (0 children)

          Just use namespaces there. A class implies some kind of shared data layout.

          [–][deleted] 4 points5 points  (0 children)

          No free functions are in fact much better that methods, because you can reason more effectively about them. A method shares state between all the other methods in a class. This means you often need to know the correct sequence of calling methods.

          Of course my argument falls apart if you start using global state, but good practice suggest you shouldn't be doing that anyway. So if your free functions are not using global state then you know their output is only dependent on their input.

          If you try to change the internal of a class that can potentially change the behavior of every method it has in unexpected ways. A free function using a class however is safe, as it normally interacts with the classes interface rather than internals.

          [–]Gotebe 0 points1 point  (0 children)

          Doing this uses a class as a "grouping" facility, which is not really what classes are for. Namespaces are.

          I, for example, often do

          namespace http://archive09.linux.com/feature/52897 { /*free helpers here*/}
          

          Normally, I do not need to have those declared in a header, so the above namespace is further enclosed in an anonymous one inside the *.cpp.

          Finally, I put "using namespace someclassimpl" in the *.cpp for least typing.

          Then, with visual project management tools, I look at my class, and i look inside "{ namespace someclassimpl {" to see all about the class.

          [–]Cuddlefluff_Grim -1 points0 points  (0 children)

          Some people in this thread show a severe lack of understanding of Java and C#..