56
$\begingroup$

In my computational science PhD program, we are working almost exclusively in C++ and Fortran. It seems like some professors prefer one over the other. I am wondering which one is 'better' or if one is better than the other in a certain circumstance.

$\endgroup$
  • 12
    $\begingroup$ A mix of a high and low level language is better than exclusively using either, in my opinion. E.g. I use Python + C++. $\endgroup$ – Faheem Mitha Dec 8 '11 at 7:22
  • 2
    $\begingroup$ The answers to this question will be almost purely subjective and thus I'm not sure this question is appropriate. $\endgroup$ – Jeff Jul 23 '13 at 6:55

12 Answers 12

61
$\begingroup$

As so often, the choice depends on (1) the problem you are trying to solve, (2) the skills you have, and (3) the people you work with (unless it's a solo project). I'll leave (3) aside for the moment because it depends on everyone's individual situation.

Problem dependence: Fortran excels at array processing. If your problem can be described in terms of simple data structures and in particular arrays, Fortran is well adapted. Fortran programmers end up using arrays even in non-obvious cases (e.g. for representing graphs). C++ is better suited for complex and highly dynamic data structures.

Skill dependence: it takes a lot more programming experience to write good C++ programs than to write good Fortran programs. If you start out with little programming experience and only have so much time to learn that aspect of your job, you probably get a better return on investment learning Fortran than learning C++. Assuming, of course, that your problem is suited to Fortran.

However, there's more to programming than just Fortran and C++. I'd recommend to anyone going into computational science to start with a dynamic high-level language such as Python. Always remember that your time is more valuable than CPU time!

$\endgroup$
  • 17
    $\begingroup$ "Always remember that your time is more valuable than CPU time!" As someone who works in HPC I disagree with that part; everything else is spot on. $\endgroup$ – Levi Morrison Mar 7 '13 at 16:32
  • 19
    $\begingroup$ "Always remember that your time is more valuble than CPU time!" As someone who works in scientific research, I couldn't agree more with that part. $\endgroup$ – decvalts Jul 13 '14 at 9:02
  • 3
    $\begingroup$ "Always remember that your time is more valuable than CPU time!" - I'd like to throw in my 2 cents - using several hundred nodes, each with 10+ cores to run some program for several weeks can be construed as a horrible waste of a most precious resource, if a couple more weeks could produce a code that runs in only a couple of days. Those HPC clusters are a rare and expensive common resource. $\endgroup$ – Dani_l Sep 21 '15 at 13:58
  • $\begingroup$ "Always remember that your time is more valuble than CPU time!", code for a week but run for a month, this's quite usual sir! $\endgroup$ – fronthem Mar 10 '16 at 22:00
  • 6
    $\begingroup$ "Always remember that your time is more valuable than CPU time!", I would rather code for a month and run in a week! - more can be done once the code is written and others will find the code you write more useful too. $\endgroup$ – Charles Apr 18 '16 at 16:58
37
$\begingroup$

I think that both C++ and Fortran are good enough and work well.

However I think that Fortran is better for numeric scientific computing, for algorithms that can be expressed using arrays and don't need other sophisticated data structures, so in fields like finite differences/elements, PDE solvers, electronic structure calculations. Fortran is a domain specific language. In particular I think that it is easier to write fast programs in Fortran than in C++, by a scientist (not necessarily a computer science expert).

C++ is a general purpose language, so one can express any algorithm in it, and it is most definitely better for algorithms that can't be expressed using arrays, from HPC field probably some graphs, mesh generators, symbolic manipulation and so on.

It is also possible to write array algorithms in C++, but in my experience, it requires much more computer science knowledge and in general more work (i.e. one needs to create or reuse classes for array manipulation, and handle memory management by hand or using some library like Teuchos from Trilinos). Non-experts tend to write pretty good Fortran programs, but horrible C++ programs (talking from my own experience).

Disclaimer: I personally like Fortran a lot and I prefer it over C++ for numeric computing. I have spent over 2 years of programming in C++ daily, and almost a year programming in modern Fortran daily (in finite elements area). I use Python and Cython a lot too.

$\endgroup$
  • 1
    $\begingroup$ One up for the first answer being balanced. I think C++ and Fortran are by far not the only possibilities in contemporary HPC. I think it is good to know the strength and weak spots when you decide for Fortran, C++ or Python (or whatever you like). I have seen 20.000 lines of Fortran in one single file, organicly grown over some decades. I personally would not use for anything other than isolated heavy array computing. Not even for anything related to output. So far for a biased comment. $\endgroup$ – shuhalo Dec 8 '11 at 8:16
  • 6
    $\begingroup$ I couldn't disagree with this response more. Our finite element code would not have been possible to write in Fortran. In fact, it started 15 years ago as a mix of plain C and Fortran (the latter being for the numerically intensive parts of the method), and it gradually moved to pure C and then to C++ over the course of several years. The code got consistently shorter, faster, and easier to understand, and it was more capable after each iteration. I agree with others that point out that C++ gives you plenty of rope to shoot yourself with. Pick the language you're most comfortable with. $\endgroup$ – Bill Barth Dec 8 '11 at 14:18
  • 6
    $\begingroup$ Bill, did you use modern Fortran (90 and later additions?). This is very important (I should have been more explicit in my answer about this). Of course, "20.000 lines of Fortran", or f77 usually is not better than well written C++. $\endgroup$ – Ondřej Čertík Dec 13 '11 at 6:12
  • 1
    $\begingroup$ @OndřejČertík: I think that if you believe that modern finite element programs use "simple" data structures, then you haven't looked at any of them recently. Try implementing adaptive finite elements, hp methods, or multigrid on unstructured meshes using simple data structures. Bill is spot on and I believe I can speak for him in saying that using "modern Fortran" would have made hardly more than a small difference. $\endgroup$ – Wolfgang Bangerth Mar 24 '12 at 8:30
  • 6
    $\begingroup$ @WolfgangBangerth, see for example Phaml (math.nist.gov/phaml) for a Fortran implementation of pretty much everything that you mentioned. $\endgroup$ – Ondřej Čertík Apr 22 '12 at 4:04
31
$\begingroup$

I'm also throwing my two cents in kind of late, but I've only just seen this thread and I feel that, for posterity, there are a few points that desperately need to be made.

Note in the following that I will talk about C and not C++. Why? Well, otherwise it's apples and oranges to compare a full-fledged dynamically typed object-oriented language with something as static as Fortran. Yes, some modern implementations of the latest Fortran standards can do more than just that, but very few people actually use them, and so when we speak of Fortran, we think simple, static, and imperative language. That's where C is too, so I'll replace C with C++ for the following.

First of all, any discussion of Fortran/C having better compilers is moot. Dedicated C/Fortran compilers are a thing of the past. Both gcc/gfortran and icc/ifc are just different front-ends to the same back-end, i.e. your program will be transformed into an abstract description by the front-end and then optimized and assembled by the back-end. If you write, semantically, the same code in Fortran or in C, the compiler will, in both cases, produce the same assembly which will run just as fast.

This now leads to my second point: why do we still see differences? The problem is that most comparisons are made by Fortran programmers trying something in C or vice-versa. Ever notice how most authors or poets prefer to write in their native languages? Would you want to write poetry in a language in which you don't feel completely confident or at home? Of course not... I myself consider C to be my "native" programming language. I did, however, also spend three years working in a group that used only Fortran, in which I have achieved a certain level of fluency. I would, however, never write anything on my own in Fortran since I'm more comfortable with C and, as a consequence, the resulting code will be better, whatever you define that as.

So the main difference is in the programmer, not the language. So there are no differences? Well, not quite. Here are a few examples:

  • SIMD: Whether it's SSE, SSE3 or AltiVec, if you want to use them in Fortran, you better hope and pray that the compiler guesses exactly what you want and does it so. Good luck. In C you generally have intrinsic functions for each architecture, or, more recently, general SIMD vector types in gcc. Most Fortran compilers will only use SIMD instructions to unroll loops, but if you have a kernel which works on short vectors of data in a non-obvious way, the compiler will very probably not see it.

  • Different hardware architectures: The whole CUDA architecture is built around kernels in C. Yes, the Portland Group now has a CUDA-capable fortran compiler too, but it's commercial, and most importantly, it's not from NVIDIA. Same goes for OpenCL, for which the best I could find is a recent project which only supports a few basic calls.

  • Parallel programming: Yes, both MPI and OpenMP work just fine with both C and Fortran. However, if you want real control of your threads, i.e. if you have a fully dynamic shared-memory computation, you'll be out in the cold with Fortran. In C you have the standard pthreads which, while not warm and fuzzy, will still get you through the storm. In general, most computations that rely on access to the operating system, e.g. threads, processes, file system, etc... are better served with C. Oh, and don't try to do your own networking with Fortran.

  • Ease of use: Fortran is closer to Matlab than C is. Once you've gotten over all the different keywords and how to declare variables, the rest of the code looks like Matlab, making it more accessible to users with limited programming experience.

  • Interoperability: When you create a struct in C, the layout of the actual data is straight-forward and deterministic. In Fortran, if you use pointer arrays or structured data, the actual layout of the data is strongly compiler-dependent, not straight-forward, and usually completely undocumented. You can call C from Fortran and vice-versa, but don't start thinking it may be as easy to pass anything more than a static array from one to the other and back.

This is all somewhat geeky, low-level stuff, but this is High-Performance Computing we're talking about, right? If you're not interested in how to best exploit the underlying hardware paradigms, i.e. implementing and/or developing algorithms which are best for shared/distributed memory, threads, SIMD vectorisation, GPUs using SIMT, and so-on, then you're just doing math on a computer.

This has gotten much longer that anything I entended, so here's a summary -- a set of take home messages of sorts:

  • You will write the best code you can in the language which you know best.
  • There is no difference in the quality of code produced by two compilers which use the same back-end -- it is us who write bad code in one language or another.
  • Despite feeling more low-level, Fortran is quite a high-level abstraction and won't let you access certain hardware/OS features directly, e.g. SIMD, threads, networking, etc...
$\endgroup$
  • 5
    $\begingroup$ Good response. I don't think however your final comment is necessarily true. I'm a C programmer myself, but you get access to low level things in Fortran through good programming practices. The ideal way to utilize things like SIMD ops is to write code which strongly suggests it (blocking loops out, for example) and let the compiler do it for you. For threading, simply use openMP (pthreads is also usable with some extra work). Fortran has all of the things you mention it doesn't, just at a level that matters to its typical user: numerical. $\endgroup$ – Reid.Atcheson Feb 4 '12 at 17:31
  • $\begingroup$ @Reid.Atcheson: Well, if you block-out everything such that the compiler will catch it, then it will work automagically both in C and in Fortran. The problem is, though, how far do you want to trust your compiler? And why do you want to have to trust it in cases when you know exactly what you want done? OpenMP does threading, yes, but block-wise. You can trick it into getting different thread pools to do different things, but that is just mis-using OpenMP. Pthreads for Fortran are just wrappers to the C functions. I agree, though, that Fortran is easier if you're not into the details. $\endgroup$ – Pedro Feb 4 '12 at 18:10
  • 1
    $\begingroup$ Sure you aren't going to get full-blown 99% peak efficiency relying on the compiler, but you can easily come quite close. Beyond this you either have to use intrinsics or inline ASM. You have to make concessions somewhere for overall programmer efficiency, that's why programming languages exist in the first place. At the stage that you actually are insane enough to get into the details of intrinsics or ASM (I have been a few times), Fortran isn't a crutch. You'd know how to link in your assembled hand-optimized code anyways. $\endgroup$ – Reid.Atcheson Feb 4 '12 at 18:19
  • $\begingroup$ @Reid.Atcheson: Well, I'd argue that for parallel HPC applications, you may well end up far below 99% peak efficiency... And the gcc vector types make using intrinsics a non-issue :) $\endgroup$ – Pedro Feb 4 '12 at 19:11
  • 1
    $\begingroup$ @Pedro, Brilliant post. Absolutely brilliant. Thanks a lot for posting. Just found it while randomly rummaging through interesting threads. $\endgroup$ – Inquest Mar 20 '12 at 16:47
16
$\begingroup$

From my 15 years of thinking about scientific software: If your code runs 25% faster because you write it in Fortran, but it takes you 4 times as long to write it (no STL, difficulty implementing complex data structures, etc), then Fortran only wins if you spend a significant fraction of your day twiddling thumbs and waiting for your computations to finish. Given that for almost all of us the most valuable thing is our own time, the conclusion is this: use the language that allows you to develop, debug and test your code the fastest, within reason ignoring that it may be slower than maybe possible if you wrote it in Fortran.

$\endgroup$
13
$\begingroup$

My approach has been to use C++ for everything but computational kernels, which are usually best written in assembly; this buys you all of the performance of the traditional HPC approach but allows you to simplify the interface, e.g., by overloading computational kernels like SGEMM/DGEMM/CGEMM/ZGEMM into a single routine, say Gemm. Clearly the abstraction level can be raised much higher by avoiding raw pointers and switching to opaque classes, but it is a nice first step.

I find the largest downside of C++ to overwhelmingly be the increase in compilation time, but, in my experience, the savings in development time more than make up for it. Another downside is that vendor C++ compilers tend to have more bugs than vendor C and Fortran compilers. In the past year, I think I have run into nearly ten bugs in C++ compilers.

With all of that said, I think that the undoing of scientific packages written in low-level languages (and Fortran) is the reluctance to expose convenient interfaces for sophisticated data structures: most people are satisfied with the Fortran BLAS interface, as it only requires pointers and leading dimensions to describe matrices, but few people would argue that the usual 40-integer Fortran sparse-direct solver interface is anything close to convenient (cf. UHM, SuperLU, PETSc, and Trilinos).

In summary, I argue for using assembly for low-level computational kernels, but higher level languages for everything else, especially when operating on non-trivial data structures.

Note that this post resulted in this comparison of the performance of C and Fortran on the kernel $y := \alpha x + y$.

$\endgroup$
  • 2
    $\begingroup$ Why wouldn't you trust a standard C compiler with appropriate optimization enabled for the purpose of compiling small kernels? At that level of code size and complexity the difference in what a compiler could pull out of it is unclear. $\endgroup$ – Peter Brune Dec 9 '11 at 5:13
  • 1
    $\begingroup$ I have talked with several people who have told me that, even with appropriate restrict usage, their Fortran was still faster than their C and/or C++ code for some operation like an explicit matrix transpose. I'm not saying that it's impossible to make the C or C++ code as fast, but that the Fortran compiler tends to do a better job. $\endgroup$ – Jack Poulson Dec 9 '11 at 5:58
  • $\begingroup$ I have the same experience with the "restrict" keyword (my simple Fortran code was always a little faster). But my expertise is limited, and I simply don't have time to invest into understanding the generated assembly from gcc. So I simply use Fortran, it's simple and it's fast. $\endgroup$ – Ondřej Čertík Dec 13 '11 at 6:15
  • $\begingroup$ @JackPoulson: The compiler argument is something I hear quite a bit from the Fortran community. Unfortunately, most compilers, e.g. gcc or ifc/icc, use different language front-ends for the same back-end. The machinery doing the optimization and code generation is identical and therefore the differences in the results are most probably due to differences in the familiarity of the programmer with the underlying language... $\endgroup$ – Pedro Feb 4 '12 at 12:37
  • 1
    $\begingroup$ Just to give a bit of perspective on the often-repeated, rarely-validated claim that Fortran is faster on numerical kernels: A while back we noticed that the sparse matrix-vector multiply in Trilinos' Epetra package was 30% slower than the one in deal.II. The former was written in straight forward Fortran 77, the latter in straight forward C without the use of 'restrict'. Both had around 10-15 lines of code. Today, Trilinos uses the piece of code hoisted from deal.II. I'm sure one can find lots of cases where F77 is faster than C. The point is that isn't universally so any more today. $\endgroup$ – Wolfgang Bangerth Mar 24 '12 at 8:37
8
$\begingroup$

Since I am new here, I was looking through old questions and found this one. Hopefully it's not taboo to answer old ones!

Since no one else has mentioned this, figured I would. Fortran 2003 is almost fully supported by most of the major compilers (intel, ibm, cray, NAG, PCG) even gcc with the (soon-to-be) newest release 4.7. Fortran 2003 (and 2008) is an object oriented language, albeit a bit more verbose than C++. One of things that I think is nice about Fortran is the fact that the standard committee see's scientific computing as it's primary audience (I thank Damian Rouson for pointing this out to me the other day).

I bring this all up not so that C++ programmers become Fortran programmers, but so that Fortran people know that they have more options now besides switching to C++ or emulating object oriented concepts in Fortran 90/95.

One caveat I will add is that there is a cost to being on the bleeding edge of what's implemented in the compilers. If you undertake a major project in Fortran 2003 right now you will stumble across bugs and continually need to update your compiler (especially if you use gcc), though this has gotten significantly better in the past few months!

$\endgroup$
7
$\begingroup$

The problem with C++ is that you have numerous chances to ruin performance, for instance by blindly using STL, exceptions, classes (virtual overhead plus alignment problems), operator overloading (redundant new/deletes) or templates (never-ending compilation and cryptic errors seem benign, but you can waste hours this way).

However, more you gain better access to general libraries and possibly grater visibility of your code (although this strongly depends on the field, and you still have pure C). And you can still compensate the Fortran's lack of flexibility by wrapping its code in a script language like R, Lush, Matlab/Scilab or even Python, Ruby or Lua.

$\endgroup$
  • 1
    $\begingroup$ It is generally a bad idea to apply low-level techniques in high-level languages. For example, the STL is designed to operate on a very abstract level. One has to be aware what the interface is designed for, use it for this task and then get out of the compilers way. $\endgroup$ – shuhalo Dec 8 '11 at 19:51
  • 2
    $\begingroup$ I think both mbq's and Martin's points are unfair. Yes, there are ways to shoot yourself in the foot if you try to implement a numeric vector for linear algebra purposes using std::list<double>. But that's a silly argument: at least C++ has a linked list class that you can use, while Fortran doesn't. It's like saying "Cars drive at such high speed that you could crash into a wall and get injured; you should use horse-drawn carriages instead." It's just a silly idea to trash a high-level language that also supports low-level stuff (e.g. C++) for having high-level features. $\endgroup$ – Wolfgang Bangerth Mar 23 '12 at 17:41
  • $\begingroup$ @WolfgangBangerth No, now you are hurting Fortran -- it is as "low-level" as bacteria are "less evolved" then humans. If you want a car analogy, it should be more like "you can use both Jeep and Lexus to cross a swampy byway, but using the first one hurts less". $\endgroup$ – mbq Mar 23 '12 at 19:13
  • 1
    $\begingroup$ I appreciate your opinion, but I do maintain that Fortran isn't as evolved as C++ is :-) $\endgroup$ – Wolfgang Bangerth Mar 23 '12 at 21:37
7
$\begingroup$

Three facts:

  • F77-style n-dimensional arrays in C: No problem using CnD (a shameless plug, admittedly)

  • F90's module system is poorly designed and hostile to build environments. (A module's name doesn't have to match its filename, e.g.)

  • Fortran does not support refactoring well. Pulling some bit of functionality out of a function requires you to touch four places: Actual code, variable declarations, argument declarations, and argument list. C gets by with two places to touch. This compounds the effect of the failure to manage data well (described below): Since small-scale modularity is so painful, just about everybody writes gigantic subroutines.

One personal impression:

  • Fortran does not work well for managing data. Try returning a pointer to a user-opaque data structure in F77 or F90. (transfer(), here we come)
$\endgroup$
  • $\begingroup$ Hi Andreas! CnD is interesting, I didn't know about it. Ah, you wrote it. :) (f90 also supports slicing, allocatable for arrays and most importantly -- array syntax for multiplication, addition and so on.) I use CMake with Fortran and it works great with modules. What exactly is "argument list"? I don't think I use these, so only 3 places are needed to modify. In C, you typically need to modify the actual code, parameters and a header file, so it's also 3 places (most definitely in C++). Yes, transfer() isn't super nice, but typically you don't need it in practice. $\endgroup$ – Ondřej Čertík Dec 13 '11 at 6:24
  • 3
    $\begingroup$ Refactoring modern fortran is trivial with proper IDEs, like Photran in eclipse. $\endgroup$ – user389 Feb 5 '12 at 0:37
  • 2
    $\begingroup$ "A module's name doesn't have to match its filename, e.g" You must be joking, you can have many modules in one file. Some of them spanning only a couple of lines. They are much easier to create if you do not have to create a file for each of them. $\endgroup$ – Vladimir F Apr 18 '15 at 14:35
  • 1
    $\begingroup$ Just wanted to add to what @user389 said that, while Photran is great and is the only Fortran IDE that allows refactorings, its parser fails all the time. On the other hand, there's no need to comment on the fact that Eclipse is memory-hungry. $\endgroup$ – astrojuanlu Jan 19 '16 at 10:17
5
$\begingroup$

Fortran is optimized for array/matrix computations and is a thorough pain to work with for any type of text parsing. C and C++ may not match up with Fortran in numerical computing (it's close),but I find it much easier to process text and organize data (i.e. custom data structures) with C/C++.

As others have mentioned, don't count out dynamic interpreted languages (Python et al). They may not offer the face-melting speed of Fortan up front, but they allow you to focus more on solving your computational problem than all the details of implementation. Often you can implement a solution in Python, and if the performance is unacceptable, do some profiling, identify the problem areas, and either optimize that code using Cython or re-implement the entire program in a compiled language. Once you have the problem-solving logic fleshed out, the rest is just implementation and, with a good understanding of computing fundamentals, should be straightforward to represent in any variety of programming languages.

$\endgroup$
  • $\begingroup$ That's right. For text parsing I also use Python. $\endgroup$ – Ondřej Čertík Dec 13 '11 at 6:27
  • $\begingroup$ You can also implement part of a Python script in a compiled language e.g. C++ and hook it in. E.g. Boost Python, Swig etc. $\endgroup$ – Faheem Mitha Dec 13 '11 at 8:05
4
$\begingroup$

I'm currently working at one of the national labs. Most of the folks around me are mechanical engineers. Chatting with some of the folks in the HPC groups, they're doing mostly Linux and mostly C++. The group I'm currently in does mostly desktop applications and we use Windows and in descending order: C#, FORTRAN, Python, VBA and VB (6, not .NET). Some of the simulation engines we use were written at other national labs in FORTRAN.

$\endgroup$
4
$\begingroup$

Sorry for digging up an old thread but it seems that even in 2015, Fortran is being used a lot.

I just came across this (alternate link) list which basically is a list of 13 codes approved by DOE's OCLF facility to run on the 300-petaFLOPS Summit machine which will be made available to researchers in 2018. I tried to find the main language used for the code (based on a quick google search) and here is what I found:

XGC Fortran

SPECFEM Fortran

ACME Fortran (Bunch of climate codes)

DIRAC Fortran (Mostly)

FLASH Fortran

GTC Fortran

HACC C/C++

LS-DALTON Fortran (some C)

NAMD C/C++

NUCCOR Fortran

NWCHEM Fortran

QMCPACK C++

RAPTOR Fortran

So out of 13 codes, at least 10 (based on my quick search) appear to be written in Fortran. Not bad for a 50 year old language.

NOTE: I am well aware that language comparisons are useless but given the number of folks (specially C++ users) that bad-mouth Fortran, I thought it might be worthwhile to mention it.

$\endgroup$
  • 3
    $\begingroup$ I disagree, because my experience at the national labs has, if anything, been the opposite. Most of the new projects I see at Lawrence Livermore are written in C++, and most of the new (or actively maintained) state-of-the-art open-source libraries in ODE solvers, FEM discretizations, and general-purpose scientific computing libraries seem to be in C or C++. Fortran seems to be mainly used in projects that use existing/legacy libraries; I don't see a lot of big, new projects using Fortran, independent of what I think about the language. $\endgroup$ – Geoff Oxberry Apr 17 '15 at 5:32
  • $\begingroup$ Some density functional theory codes also written in Fortran include VASP and CASTEP, though as @GeoffOxberry points out, new projects do perhaps tend towards C++. $\endgroup$ – dr.blochwave Apr 20 '15 at 9:44
  • $\begingroup$ @blochwave As you can read in the link, the projects are for a new machine (with accelerators etc.) that will be online in 2018. So its not like they take a 25 year code and compile it, hoping to run with at good performance. I am quite sure large parts of the codes in the above list have or are been rewritten, as in new code. A number of "new" climate codes are in Fortran as well and used by many agencies in a number of countries. $\endgroup$ – stali Apr 20 '15 at 11:43
0
$\begingroup$

What Jack P. I think is trying to say is that you should mix and match. A good piece of software is carefully layered. Different layers may map more naturally, or efficiently, to different languages. You should choose the most appropriate language for each layer. You should also understand how languages can interoperate, which may affect what language you choose for what layer.

A better question is what examples of excellently designed software are out there that are worth studying to learn about how to design layered software.

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.