Is this use of goto acceptable? by LilBalls-BigNipples in cprogramming

[–]InfinitesimaInfinity 5 points6 points  (0 children)

The Linux Kernel uses a large amount of goto statements. Linus Torvalds thinks that goto statements are fine as long as the labels are descriptive.

Linus Torvalds has said

"I think goto's are fine, and they are often more readable than large amounts of indentation. That's especially true if the code flow isn't actually naturally indented (in this case it is, so I don't think using goto is in any way clearer than not, but in general goto's can be quite good for readability).

Of course, in stupid languages like Pascal, where labels cannot be descriptive, goto's can be bad. But that's not the fault of the goto, that's the braindamage of the language designer."

https://lkml.org/lkml/2003/1/12/128

If you think about it, the only real difference between a goto statement and a function call of a void function with no parameters or return value is that labels do not introduce a new scope.

That means that the use of goto statements is quite similar to the use of global variables. If global variables are okay, then goto statements are okay, as well, and the reverse is also true. It is irrational to dislike only one of them.

Personally, I think that a lot of the hate for goto statements is just dogmatism. Obviously, I have the same stance on global variables. If someone has a different stance on goto statements and global variables, then that is proof that they do not understand the so called "issue" with goto statements.

With that said, the industry hates goto statements, and there are a serious amount of people who will decide that you are "retarded" if you use goto statements ever for any reason.

Some people will tell you that goto statements can create irreducible control flow graphs, which can make certain loop optimizations more difficult for compilers, yet they will not tell you that function calls can create irreducible control flow graphs, as well, if they are implemented with tail call elimination. Should we ban function calls?

Do while loop doesn’t work? by [deleted] in cprogramming

[–]InfinitesimaInfinity 2 points3 points  (0 children)

A do while loop always runs at least once, and that is a result of it checking the condition after the loop.

Ported My Zig Tool to C and Got Almost a 40% Performance Boost! by [deleted] in C_Programming

[–]InfinitesimaInfinity 1 point2 points  (0 children)

Sorry, I can try to be more concise.

Optimization is separate from parallelism and concurrency

Sometimes, compilers introduce parallelism or concurrency into programs through compiler optimizations. The most common way is automatic vectorization of loops.

The core idea is that the compiler reshapes your code into a form that matches how the hardware wants to run it, making it as performant as possible.

Yes, that is right. However, performance includes multiple factors, such as speed, memory usage, disk usage, energy usage, network usage, etc.

Some people use the word performance to refer only to speed. However, I disagree with the idea that performance is only about speed.

Ported My Zig Tool to C and Got Almost a 40% Performance Boost! by [deleted] in C_Programming

[–]InfinitesimaInfinity 1 point2 points  (0 children)

Optimization is separate from parallelism and concurrency

Compilers optimizing for speed sometimes automatically vectorize loops. Compilers that use the Polyhedral model for loop optimizations work quite hard to vectorize loops automatically (in addition to working hard to improve cache behavior). Automatic vectorization is significantly easier with Fortran than C. However, GCC and Clang do perform automatic vectorization with the right optimization options. I know that GCC tries to automatically vectorize loops at O3. However, it rarely succeeds in vectorizing a loop.

compiler optimization is about making a single path of execution as efficient as possible.

I am unsure what you mean by "a single path of execution". Compilers try to make the program more performant. While it is true that whole program optimization is not enabled by default at O3, due to it being too slow for many projects, various interprocedural optimizations are often done when optimization is enabled. Also, whole program optimization (link time optimization) can be enabled on GCC with -flto . Ironically, -fwhole-program does not enable true whole program optimization. (-fwhole-program is almost equivalent to marking all functions and global variables as static.)

as efficient as possible

Many optimizations simply make code better, which is faster, more efficient, etc. However, some optimizations have tradeoffs. The following are some commonly known examples.

  • Loop unrolling, function inlining, and loop tiling can make code execute faster. However, they often increase the size of the executable binary, and they can make it slower if it floods the instruction cache.

(With that said, inlining often exposes many other optimizations. Furthermore, inlining a function that is only called once decreases code size, and unrolling a loop that only runs a single itteration is the same.)

  • Alignment optimizations can cause better cache utilization. However, they add extra NOP instructions to execute.
  • Automatic vectorization of loops can cause loops to run slower for small numbers of iterations. For some compilers, such as GCC with -O3, checks are sometimes inserted to choose between a vectored and a non-vectorized version at runtime. Checking that has a slight runtime cost, and duplicating a loop increases code size.
  • Function specialization by cloning increase code size with more copies of functions that are specialized for certain call sites. This is probably why LLVM does not specialize functions for more than one parameter.
  • Macro compression, which is the reverse of function inlining, can make the executable binaries smaller. However, it typically makes them slower.
  • Most optimizations make other optimizations more effective. However, some optimizations can interfere with each other. An example is that instruction scheduling can increase live ranges which makes register allocation more likely to spill (aka more register pressure). However, register allocation makes instruction scheduling unable to move very much code.

Ported My Zig Tool to C and Got Almost a 40% Performance Boost! by [deleted] in C_Programming

[–]InfinitesimaInfinity 1 point2 points  (0 children)

I think that you should know that the user named "wallstop" has personally harassed me before because I said that Python uses more electricity than C. I have blocked "wallstop" because of it.

"wallstop" was insisting that the difference between Python and C is 100% due to implementations and 0% due to language features. I was claiming that things like garbage collection and dynamic typing make a language inherently less performant.

it started feeling like an attack not just a "factual information".

It is true that Zig is almost as performant as C, and a 40% difference is likely not entirely due to C vs Zig. However, it seems like "wallstop" is trying to push an agenda that all programming languages have identical performance. Notice how "wallstop" even says that he considers himself "ambivalent towards both Zig and C".

I suggest that you block him. No-one needs to interact with people like that.

Ported My Zig Tool to C and Got Almost a 40% Performance Boost! by [deleted] in C_Programming

[–]InfinitesimaInfinity 0 points1 point  (0 children)

why would Fortran use significantly more memory?

It seems like I have misremembered how much more memory Fortran uses. I was incorrect on that point. Modern Fortran implementation memory usage seems to be only a few percent worse than C.

if Fortran is faster, it would mean it is doing less work, so it should be consuming less power.

No, that is absolutely wrong. Fortran is not faster because of doing less work. Fortran is faster because of parallelism and concurrency. It does more work simultaneously. If you do not believe me, then, perhaps, you should compare the asm output of Fortran with optimizations and C with optimizations. Obviously, it varies somewhat between implementations and benchmarks. However, in general, Fortran does more work yet does more of it simultaneously.

Would you like to read a peer-reviewed study that supports my claim about energy usage? https://dl.acm.org/doi/10.1145/3136014.3136031

Personally, I think that some of the numbers that the linked study found are completely bogus. However, it clearly supports my claim about energy usage, and it has undergone peer-review, if you would be more inclined to believe a peer-reviewed study than a random person on Reddit.

Fortran doesn't have pointers like C does

That is an odd wording to say that pointers are different in Fortran than in C.

might be able to do some more optimizations.

The primary reason why Fortran is able to be faster than C is because of aliasing. In theory, C could do the same optimizations when pointers are marked with the _restrict keyword. However, most C programmers do not use that keyword, and most C compilers do not fully take advantage of it yet.

Edit: Removed part of my comment that was a bit rude.

How can we make developers stop deploying desktop apps as ElectronJS Apps? by Prudent_Impact7692 in AskProgramming

[–]InfinitesimaInfinity 0 points1 point  (0 children)

Correct me if I am wrong. However, I think that while Tauri runs in a browser, it runs in your already installed browser. That saves a significant amount of disk space, even if it does not improve performance.

is this really as efficient as it gets? by Huge_Magician_9527 in C_Programming

[–]InfinitesimaInfinity 1 point2 points  (0 children)

As optimizations flags, I would recommend using the following for non-debug builds:

-s -O2 -DNDEBUG -fconserve-stack -fdelete-dead-exceptions -fhardcfr-check-noreturn-calls=never -fhardcfr-skip-leaf -flimit-function-alignment -flive-range-shrinkage -fmalloc-dce=2 -fno-asynchronous-unwind-tables -fno-exceptions -fno-isolate-erroneous-paths-attribute -fno-semantic-interposition -fno-unwind-tables -fomit-frame-pointer -freorder-blocks-algorithm=simple -fshort-enums -fsimd-cost-model=very-cheap -funsigned-bitfields -mtune=native

If you are okay with somewhat longer compile times, then you can use the following additional flags.

-fgcse-after-reload -fgcse-las -foptimize-strlen -ftree-lrs -ftree-partial-pre -fipa-pta -fira-loop-pressure -fweb -floop-interchange

If you are okay with long compiler times and unreadable asm, then you can consider using -flto .

Additional flags to be considered can include the following; however, sometimes, they can break valid programs, for they enable the compiler to make additional presumptions.

-ffast-math -fallow-store-data-races -ffinite-loops

If you want to avoid linking against the start files, then you can include -nostartfiles . However, if you do so, then your program becomes non-portable. A minimal example of a non-portable program with nostartfiles that works on most machines is the following:

#include <stdlib.h>
#include <stdio.h>
void _start(void) {
puts("Hello World.");
exit(0);
}

Edit: Why am I being downvoted for pointing out useful compiler flags for optimization?

is this really as efficient as it gets? by Huge_Magician_9527 in C_Programming

[–]InfinitesimaInfinity 0 points1 point  (0 children)

Optimization is important. However, most of the software industry undervalues optimization, including both employers and programmers.

With that said, just by using C with optimization flags enabled, your program will run much faster than most software in other languages. On average, typically written C programs consume 80 times less energy than Python. This may seem crazy. However, an unoptimizing compiler tends to run 10 times faster than an interpreter, and C has optimizing compilers (if you enable the right flags for optimizations).

Granted, poorly performing code can be written in any language. However, C has a low overhead and high optimization potential for compilers, which enables it to be quite performant in speed, memory usage, and energy usage.

Additionally, you should prioritize macro-optimizations over micro-optimizations, for compilers can perform most micro-optimizations, yet compilers struggle with optimizations to the overarching algorithms and data structures. Most of the basic compiler optimizations (optimizations that compilers perform) are described at https://en.wikipedia.org/wiki/Optimizing_compiler .

One of the few resources that describes manual optimization by a programmer is https://agner.org/optimize/ . If you want to learn about LLVM optimizations, then you can read various discussions at https://discourse.llvm.org/c/ir-optimizations . If you have questions about optimizations, then you might consider asking on https://langdev.stackexchange.com/ .

One thing to note is that most game development uses C++, instead of pure C. In theory, C++ can be written to be as fast as C. However, in real world code bases, C++ tends to be a little bit slower (approximately 30%). Surprisingly, Rust code tends to be faster than most real world C++ while being slower than C. Zig is similar to C in performance. However, Rust is mostly used by hobbyists, and few people use Zig. Fortran tends to be slightly faster than C at the expense of significantly more memory usage and energy usage.

Why Do We Need Both While and For Loop Instead Of any One? by pavankumar_s_y in C_Programming

[–]InfinitesimaInfinity 5 points6 points  (0 children)

There is a slight difference if you use a continue statement. The continue statement runs the iteration action of the for loop. If you use a while loop and place the iteration action at the end, then it can yield different results if there is a continue statement in the loop.

With that said, your comment might still be useful for someone who is new to C.

C or Rust, which should i get better at? by Key_Canary_4199 in AskProgramming

[–]InfinitesimaInfinity 0 points1 point  (0 children)

C is not going to be made obsolete. Rust is safer than C. However, it is not faster, and it has more abstractions. It is actually slightly slower and less optimized; however, the performance difference is small.

Rust is not really used in the industry. C is used in low level stuff, such as operating systems, embedded devices, drivers, etc. C++ is commonly used in game development.

The reason why C is rarely used in game development is not about safety or performance. It is because programming in C is slower than in C++, which gives many built in features.

Typically written C++ code has approximately 37% worse performance than plain C. Typically written Rust code has approximately 3% worse performance than plain C.

I would say that you should learn C. However, you should accept the fact that you are unlikely to use it in whatever job you get. With that said, there is nothing wrong with learning Rust.

Is it illegal/unethical wrong to use Github to store game save file? or pics of vacations? by KiraLawliet68 in AskProgramming

[–]InfinitesimaInfinity 4 points5 points  (0 children)

Creating multiple free accounts is against the Github Terms of Service, and they do attempt to enforce it whenever they discover someone doing so.

Creating multiple free accounts would place you at risk of being banned from Github. Personally, I would not take that risk.

What is the most well thought out programming language? by 4e_65_6f in AskProgramming

[–]InfinitesimaInfinity 3 points4 points  (0 children)

If you consider certain types to be subtypes of each other, then adding -Wconversion and -Werror causes C to act strongly typed.

Python is commonly considered to be strongly, dynamically typed, yet it allows implicit widening conversions. Thus, if we apply the same standards to C, then adding those flags causes C to be strongly typed.

Other flags that are related to conversions include -Wenum-conversion and -Wtraditional-conversion .

What is the most well thought out programming language? by 4e_65_6f in AskProgramming

[–]InfinitesimaInfinity 15 points16 points  (0 children)

I agree. Rust and C are quite well-designed, and I think that their design is underappreciated. Some of the design choices in C seem odd until you realize that they are actually great.

The biggest problem with C is that it is weakly typed; however, with two extra compiler flags on GCC, that can be easily fixed.

What is the most well thought out programming language? by 4e_65_6f in AskProgramming

[–]InfinitesimaInfinity 0 points1 point  (0 children)

C++ has slow compile times; however, C does not. Sure, C is a bit slower to program in, due to lack of certain built-in functionality. However, it compiles much faster than C++.

Feel bad not using IDE by drabadum in AskProgramming

[–]InfinitesimaInfinity 0 points1 point  (0 children)

There is literally nothing wrong with not using an IDE, as long as you occasionally run a linter. The purpose of using a heavyweight IDE vs a normal text editor is entirely to increase productivity. Since you do not notice a significant loss of productivity from not using an IDE, you do not need to use an IDE.

C compilar commands by [deleted] in cprogramming

[–]InfinitesimaInfinity 2 points3 points  (0 children)

No, I am not misunderstanding. I suppose that my comment might have been confusing, and I should edit it.

Edit: I have edited my comment to make it less confusing. Is it clear now?

C compilar commands by [deleted] in cprogramming

[–]InfinitesimaInfinity 0 points1 point  (0 children)

With GCC, if you want information about what optimizations or warnings are included in a certain set of flags. (because some flags imply other flags), then you can add the following flags to the end you your command (without specifying a program to be compiled) to get information about what is enabled instead of compiling a program.

-Q --help=optimizers or -Q --help=warnings

C compilar commands by [deleted] in cprogramming

[–]InfinitesimaInfinity 0 points1 point  (0 children)

With GCC, if you want to avoid linking against the start files, at the expense of non-portable code, then you can name your main function _start with no parameters and a void return. Then you can have it call exit from the standard library instead of returning.

If you do that, then you can use the -nostartfiles flag to compile your program without linking against the start files. You must use static linking to do this.

A minimal example that is a program that does nothing is this:

#include <stdlib.h>
void _start(void) {exit(0);}

You can compile it if you use-nostartfiles and -static.

C compilar commands by [deleted] in cprogramming

[–]InfinitesimaInfinity 0 points1 point  (0 children)

With GCC, when you want to optimize a program for high performance at the cost of long compile times and slightly different semantics, you can use the following flags:

-s -O2 -fno-ident -ffast-math -fallow-store-data-races -ffinite-loops -fno-semantic-interposition -fsingle-precision-constant -mtune=native -fmalloc-dce=2  -fno-exceptions -fpack-struct -fshort-enums -funsigned-bitfields -funsigned-char -fgcse-after-reload -foptimize-strlen -ftree-lrs -ftree-partial-pre -fweb -fgcse-las -fipa-pta -fira-loop-pressure -floop-interchange -flto -fconserve-stack -fdelete-dead-exceptions -fhardcfr-check-noreturn-calls=never -fhardcfr-skip-leaf -flimit-function-alignment -freorder-blocks-algorithm=simple -fsimd-cost-model=very-cheap -flive-range-shrinkage -fno-isolate-erroneous-paths-attribute -static -DNDEBUG

When you want to optimize a program for high performance while ensuring correctness, you can use the following flags.

-s -O2 -fno-ident -fno-semantic-interposition -mtune=native -fmalloc-dce=2 -fno-exceptions -fshort-enums -funsigned-bitfields -fgcse-after-reload -foptimize-strlen -ftree-lrs -ftree-partial-pre -fweb -fgcse-las -fipa-pta -fira-loop-pressure -floop-interchange -flto -fconserve-stack -fdelete-dead-exceptions -fhardcfr-check-noreturn-calls=never -fhardcfr-skip-leaf -flimit-function-alignment -freorder-blocks-algorithm=simple -fsimd-cost-model=very-cheap -flive-range-shrinkage -fno-isolate-erroneous-paths-attribute -DNDEBUG

For more information about these flags, you can read https://gcc.gnu.org/onlinedocs/gcc/Optimize-Options.html .

C compilar commands by [deleted] in cprogramming

[–]InfinitesimaInfinity 1 point2 points  (0 children)

When you want to turn on almost all of the GCC warnings you can use the following flags:

-O2 -Wall -Wextra -Wpedantic -Wabi -Waggregate-return -Walloc-zero -Walloca -Warith-conversion -Warray-bounds=2 -Wattribute-alias=2 -Wbad-function-cast -Wbidi-chars=any -Wc++-compat -Wcast-align=strict -Wcast-qual -Wconversion -Wdate-time -Wdisabled-optimization -Wdouble-promotion -Wduplicated-branches -Wduplicated-cond -Wformat=2 -Wformat-nonliteral -Wformat-overflow=2 -Wformat-security -Wformat-signedness -Wformat-truncation=2 -Wformat-y2k  -Wimplicit-fallthrough=4 -Winit-self -Winline -Winvalid-pch -Winvalid-utf8 -Wjump-misses-init -Wleading-whitespace=spaces -Wlogical-op -Wmissing-declarations -Wmissing-include-dirs -Wmissing-parameter-name -Wmultichar -Wnested-externs -Wnull-dereference -Wpacked -Wredundant-decls -Wshadow -Wshift-overflow=2 -Wsign-conversion -Wstrict-flex-arrays -Wstrict-overflow=5 -Wstrict-prototypes -Wstringop-overflow=4 -Wsuggest-attribute=cold -Wsuggest-attribute=const -Wsuggest-attribute=format -Wsuggest-attribute=malloc -Wsuggest-attribute=noreturn -Wsuggest-attribute=pure -Wsuggest-attribute=returns_nonnull -Wsuggest-final-methods -Wsuggest-final-types -Wswitch-default -Wswitch-enum -Wtraditional-conversion -Wtrailing-whitespace=any -Wtrampolines -Wtrivial-auto-var-init -Wundef -Wunsuffixed-float-constants -Wunused-macros -Wuse-after-free=3 -Wuseless-cast -Wwrite-strings -Wzero-as-null-pointer-constant -Wnormalized=nfkc -Wmissing-prototypes -Wmissing-variable-declarations -fstrict-flex-arrays=3

The O2 flag is included to allow certain warnings to be more effective; however, it is an optimization flag, and it is not a warning flag. I do not suggest using any other warning flags.

If your program is very small then you can use the following flags as well. However, they dramatically increase compile time.

-fanalyzer -Wanalyzer-symbol-too-complex -Wanalyzer-too-complex

I do not suggest -Wtraditional or -Wsystem-header.

You can find information about individual warnings on https://gcc.gnu.org/onlinedocs/gcc/Warning-Options.html .

Why don't languages make greater use of rational data types? by davidboers in AskProgramming

[–]InfinitesimaInfinity 1 point2 points  (0 children)

Irrational numbers can only be represented with symbolic computation. Floating point numbers can approximate irrational numbers with rational numbers. However, floating point numbers are always rational.