Glyphin » Forums » C or C++
Telash
Mikael Johansson
52 posts
1 project
#13180 C or C++
3 weeks, 2 days ago

So far I have been coding Glyphin in C, and I have no issues with it at all. However, I know Glyphin will keep growing to a much bigger program that anything I have done before. In fact, its already bigger then anything I have done before. So it kind of is uncharted territory for me.

Many people say it is alot easier to work with big project in C++ then C, other say C++ is garbage.

So, should I start converting the program to C++? C or C++? Convince me that your opinion is the right one :D

It is very important that I dont loose any performance, and I have no interest in the std library.

The biggest obstacle to great software is lack of motivation. Motivate each other!
mmozeiko
Mārtiņš Možeiko
1485 posts
1 project
#13181 C or C++
3 weeks, 2 days ago

If everything works right now, then what exactly additional things / easier things you will get by writing code in C++?
Telash
Mikael Johansson
52 posts
1 project
#13182 C or C++
3 weeks, 2 days ago

Well, that kind of is my question. Maybe people that have tried building a bit bigger programs in C (50k lines or more) have run into issues? I know the theoretical pros and cons, but if its one thing I have learned, its that what's theoretically good or bad, isn't always what's good and bad in practice over time.

The biggest obstacle to great software is lack of motivation. Motivate each other!
mmozeiko
Mārtiņš Možeiko
1485 posts
1 project
#13183 C or C++
3 weeks, 2 days ago Edited by Mārtiņš Možeiko on Sept. 29, 2017, 7:11 p.m.

There is 0 difference between building larger C or C++ code.

To me it seems very silly reason to switch to different language just because somebody else potentially have had issues with language you use. As long as everything works and is good for you, why change it.
insofaras
Alex Baines
24 posts
1 project
#13184 C or C++
3 weeks, 2 days ago

The Linux kernel is an example of a very large project written without any C++, and it's probably one of the most widely used and well regarded pieces of software in existence.

I would say use whichever you prefer; how easy the project is to work with is probably more to do with what you write than what language it's written in.
Croepha
David Butler
59 posts
1 project

I love pretty much anything technical, whether it be programming, networking, hacking or electronics.

#13185 C or C++
3 weeks, 2 days ago Edited by David Butler on Sept. 30, 2017, 2:04 a.m.

I personally like my own subset of C++. But what works for me shouldn't necessarily work well for anyone else... Each programmer is different. We all have different weaknesses and strengths... You should build all your tools, workflows, libraries, and/or choose from existing tools libraries with your own needs in mind, not anyone else's. Also your needs may vary from project to project... I would encourage you to try out things if you are curious about them, don't stay away from something just because other people don't like it, or like something else.

Also, I really don't know of any reason why C or C++ would be better at handling large number of lines of code, I can think of obscenely large programs written in either language...

Bus Error
anael
anaël seghezzi
20 posts
1 project
#13186 C or C++
3 weeks, 1 day ago

One thing for sure, a large codebase will compile faster in C than C++.

Otherwise I think that future evolution and flexibility depends more on your structural choices than the language used to describe it.
mmozeiko
Mārtiņš Možeiko
1485 posts
1 project
#13187 C or C++
3 weeks, 1 day ago

anael
One thing for sure, a large codebase will compile faster in C than C++.

That is only true if you use huge headers or header-libraries (due to templates, like STL or Boost). But that is not C++' fault. You can easily organize your code so headers are small and all implementation is hidden in .cpp. Or use unity builds. In either case - then your compile times won't be so slower than C.
Telash
Mikael Johansson
52 posts
1 project
#13188 C or C++
3 weeks, 1 day ago

Thanks for the replies. I will stick to C. I dont think that the few things I have to gain from C++ is worth it for me anyways.
The only thing I think I would use is to make the struct-specific functions into methods, constructor, destructors, and maybe a few overloaded functions, witch would save me like 1% of typing. Its just not worth loosing even a little compile-speed and/or runtime performance over that.

The biggest obstacle to great software is lack of motivation. Motivate each other!
ratchetfreak
303 posts
#13189 C or C++
3 weeks, 1 day ago

Telash
Thanks for the replies. I will stick to C. I dont think that the few things I have to gain from C++ is worth it for me anyways.
The only thing I think I would use is to make the struct-specific functions into methods, constructor, destructors, and maybe a few overloaded functions, witch would save me like 1% of typing. Its just not worth loosing even a little compile-speed and/or runtime performance over that.


Actually just because you are using a C++ compiler doesn't mean you need to use all features of C++. Handmade hero has shown that.

Those features you mentioned will not increase the compile time at all nor will they affect performance.
Telash
Mikael Johansson
52 posts
1 project
#13190 C or C++
3 weeks, 1 day ago

Interesting. Do you have any link to an unbiased report or something like that to back that up?

The biggest obstacle to great software is lack of motivation. Motivate each other!
Croepha
David Butler
59 posts
1 project

I love pretty much anything technical, whether it be programming, networking, hacking or electronics.

#13199 C or C++
2 weeks, 6 days ago Edited by David Butler on Oct. 2, 2017, 3:39 p.m.

Not sure what report you would be wanting, but if we are just talking about comparing compile times of code bases with C++ member functions vs C functions then we really don't have to worry about bias, because compile time is a pretty objective metric...

I wanted to know for sure myself, so I made a test:
  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
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
#include <stdio.h>
#include <time.h>
#include <stdlib.h>
#include <assert.h>

void build_c() {
    srand(1506883738);
    auto f = fopen("build/output.c", "w");
    assert(f);
    int funkyno = 0;
    int typeno = 0;

    while (funkyno < 10000) {
        bool has_constructor = rand()%2;
        bool has_destructor = rand()%2;
        auto type_member_count = rand()%16 + 1;
        auto method_count = rand()%16 + 1;

        fprintf(f, "typedef struct Type_%06d {\n", typeno);
        for (int i=0;i<type_member_count; i++) {
            fprintf(f, "  int member_%02d;\n", i);
        }
        fprintf(f, "} Type_%06d;\n", typeno);
        if (has_constructor) {
            fprintf(f, "void Type_%06d_constructor(Type_%06d*instance);\n", typeno, typeno);
        }
        if (has_destructor) {
            fprintf(f, "void Type_%06d_destructor(Type_%06d*instance);\n", typeno, typeno);
        }
        for (int i=0;i<method_count; i++) {
            fprintf(f, "void Type_%06d_method_%06d(Type_%06d*instance);\n", typeno, i, typeno);
        }
        if (has_constructor) {
            fprintf(f, "void Type_%06d_constructor(Type_%06d*instance) {\n", typeno, typeno);
            for (int i=0;i<type_member_count; i++) {
                if (rand()%2) fprintf(f, "  instance->member_%02d = %d;\n", i, rand()%8192);
            }
            fprintf(f, "}\n");
            funkyno++;
        }
        if (has_destructor) {
            fprintf(f, "void Type_%06d_destructor(Type_%06d*instance) {\n", typeno, typeno);
            for (int i=0;i<type_member_count; i++) {
                if (rand()%2) fprintf(f, "  instance->member_%02d = %d;\n", i, rand()%8192);
            }
            fprintf(f, "}\n");
            funkyno++;
        }
        for (int i=0;i<method_count; i++) {
            fprintf(f, "void Type_%06d_method_%06d(Type_%06d*instance) {\n", typeno, i, typeno);
            fprintf(f, "  instance->member_%02d = %d;\n", rand()%type_member_count, rand()%8192);
            fprintf(f, "}\n");
            funkyno++;
        }
        typeno++;
        fprintf(f, "");
    }
    fclose(f);
}

void build_cpp() {
    srand(1506883738);
    auto f = fopen("build/output.cpp", "w");
    assert(f);
    int funkyno = 0;
    int typeno = 0;

    while (funkyno < 10000) {
        bool has_constructor = rand()%2;
        bool has_destructor = rand()%2;
        auto type_member_count = rand()%16 + 1;
        auto method_count = rand()%16 + 1;

        fprintf(f, "struct Type_%06d {\n", typeno);
        for (int i=0;i<type_member_count; i++) {
            fprintf(f, "  int member_%02d;\n", i);
        }
        if (has_constructor) {
            fprintf(f, "  Type_%06d();\n", typeno);
            funkyno++;
        }
        if (has_destructor) {
            fprintf(f, "  ~Type_%06d();\n", typeno);
            funkyno++;
        }
        for (int i=0;i<method_count; i++) {
            fprintf(f, "  void method_%06d(); \n", i);
            funkyno++;
        }
        fprintf(f, "};\n");
        if (has_constructor) {
            fprintf(f, "Type_%06d::Type_%06d() {\n", typeno, typeno);
            for (int i=0;i<type_member_count; i++) {
                if (rand()%2) fprintf(f, "  member_%02d = %d;\n", i, rand()%8192);
            }
            fprintf(f, "}\n");
        }
        if (has_destructor) {
            fprintf(f, "Type_%06d::~Type_%06d() {\n", typeno, typeno);
            for (int i=0;i<type_member_count; i++) {
                if (rand()%2) fprintf(f, "  member_%02d = %d;\n", i, rand()%8192);
            }
            fprintf(f, "}\n");
        }
        for (int i=0;i<method_count; i++) {
            fprintf(f, "void Type_%06d::method_%06d() {\n", typeno, i);
            fprintf(f, "  member_%02d = %d;\n", rand()%type_member_count, rand()%8192);
            fprintf(f, "}\n");
        }
        typeno++;

    }
    fclose(f);
}


int main() {
    build_c();
    build_cpp();
}

To build:
 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
mkdir -p build/
time clang++ --std=gnu++11 \
 -fsanitize=address -fsanitize=undefined \
 main.cpp -o build/main.bin
build/main.bin
echo building build/output.c
wc build/output.c
echo gcc
env time gcc  -c build/output.c -o build/output.c.o
env time gcc  -c build/output.c -o build/output.c.o
env time gcc  -c build/output.c -o build/output.c.o
env time gcc  -c build/output.c -o build/output.c.o
echo clang
env time clang  -c build/output.c -o build/output.c.o
env time clang  -c build/output.c -o build/output.c.o
env time clang  -c build/output.c -o build/output.c.o
env time clang  -c build/output.c -o build/output.c.o
env echo building build/output.cpp
wc build/output.cpp
echo g++
env time g++  -c build/output.cpp -o build/output.cpp.o
env time g++  -c build/output.cpp -o build/output.cpp.o
env time g++  -c build/output.cpp -o build/output.cpp.o
env time g++  -c build/output.cpp -o build/output.cpp.o
echo clang++
env time clang++  -c build/output.cpp -o build/output.cpp.o
env time clang++  -c build/output.cpp -o build/output.cpp.o
env time clang++  -c build/output.cpp -o build/output.cpp.o
env time clang++  -c build/output.cpp -o build/output.cpp.o

And these were my results:
 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
building build/output.c
  54492  124503 1704453 build/output.c
gcc
2.94user 0.92system 0:03.98elapsed 96%CPU (0avgtext+0avgdata 183624maxresident)k
3368inputs+8424outputs (0major+61886minor)pagefaults 0swaps
2.92user 0.19system 0:03.27elapsed 95%CPU (0avgtext+0avgdata 183480maxresident)k
3368inputs+8424outputs (0major+61876minor)pagefaults 0swaps
3.24user 0.19system 0:03.90elapsed 88%CPU (0avgtext+0avgdata 183384maxresident)k
3368inputs+8424outputs (0major+61875minor)pagefaults 0swaps
2.68user 0.21system 0:03.04elapsed 95%CPU (0avgtext+0avgdata 183472maxresident)k
3368inputs+8424outputs (0major+61877minor)pagefaults 0swaps
clang
1.45user 0.07system 0:01.69elapsed 90%CPU (0avgtext+0avgdata 97296maxresident)k
3336inputs+0outputs (1major+19083minor)pagefaults 0swaps
1.33user 0.06system 0:01.53elapsed 90%CPU (0avgtext+0avgdata 97140maxresident)k
3336inputs+0outputs (1major+19043minor)pagefaults 0swaps
1.38user 0.07system 0:01.65elapsed 88%CPU (0avgtext+0avgdata 97212maxresident)k
3336inputs+0outputs (1major+19069minor)pagefaults 0swaps
1.48user 0.08system 0:01.86elapsed 83%CPU (0avgtext+0avgdata 97144maxresident)k
3336inputs+0outputs (1major+19089minor)pagefaults 0swaps
building build/output.cpp
  54492  120319 1059772 build/output.cpp
g++
2.97user 0.25system 0:03.36elapsed 95%CPU (0avgtext+0avgdata 222260maxresident)k
2104inputs+9464outputs (0major+77181minor)pagefaults 0swaps
3.02user 0.17system 0:03.41elapsed 93%CPU (0avgtext+0avgdata 223088maxresident)k
2104inputs+9464outputs (0major+76919minor)pagefaults 0swaps
2.98user 0.14system 0:03.32elapsed 93%CPU (0avgtext+0avgdata 223532maxresident)k
2104inputs+9464outputs (0major+76995minor)pagefaults 0swaps
2.97user 0.19system 0:03.31elapsed 95%CPU (0avgtext+0avgdata 222020maxresident)k
2104inputs+9464outputs (0major+77155minor)pagefaults 0swaps
clang++
1.39user 0.09system 0:01.67elapsed 89%CPU (0avgtext+0avgdata 95416maxresident)k
2072inputs+0outputs (1major+18484minor)pagefaults 0swaps
1.47user 0.08system 0:01.69elapsed 91%CPU (0avgtext+0avgdata 95192maxresident)k
2072inputs+0outputs (1major+18485minor)pagefaults 0swaps
1.48user 0.05system 0:01.69elapsed 90%CPU (0avgtext+0avgdata 95192maxresident)k
2072inputs+0outputs (1major+18492minor)pagefaults 0swaps
1.43user 0.09system 0:01.69elapsed 90%CPU (0avgtext+0avgdata 95536maxresident)k
2072inputs+0outputs (1major+18496minor)pagefaults 0swaps
exited with code 0


So, with 54K lines of code, the differences seem to be inside of the error margin, Im running in a VM on a laptop, so, later I'll try using my actual dev machine, and maybe the times will be a bit more stable and I can get some better statistics...

EDIT: So, I was a bit sleepy when I wrote the first version, I moved the rand() calls inside of the loop where I had intended them to be, so now its a little more random, also I changed my conclusion

Bus Error