New answers tagged

6

-> is a syntactic sugar. The expression a->b is simply a more pleasant way to write (*a).b So that is: evaluate a to produce a pointer dereference the pointer to produce a variable containing a structure destructure that variable to produce the variable b I couldn't find it on a C operators table. My advice is that you either look more ...


3

It's largely a matter of personal preference, although some places may make it a formal coding standard. C itself doesn't care. For my part, if I'm defining multiple functions in a single source file, I will define the called functions before the caller: void foo( void ) { ... } void bar( void ) { ... foo(); ... } int main( void ) { ... ...


1

The best place is somewhere that people can find it. In the middle of a very large file is bad. At the top is good, but others might prefer right at the bottom. Forward declaring main() doesn't help, and is often pointless anyway - because it's very unusual to explicitly call main() from within your code.


1

While I don't think that this sort of pre-processor-level “comment” is evil, I'm also not very excited about it. Your tools won't interpret it in any way and won't be able to catch any bugs caused by accidentally using a function in a way it wasn't intended to. The tag is also invisible at the call-site. Since it is really just a comment, you could equally ...


4

You can (see the Labels as Values gcc extension). It's rather doubtful that you should. Dijkstra taught us that goto was harmful. You are proposing not only using goto, and a jump table, but also a function that returns to the passed label. Understand that a function is essentially a goto (jump) with some pushing onto the stack (the stack frame). That ...


7

In standard C99 or C11 you cannot. But GCC has a language extension, label as values, which might help (and Clang/LLVM also accepts it). Even with the computed gotos that extension provides, jumping into another routine is (nearly) undefined behavior. You can jump indirectly to a label inside the same routine. You could return a label to jump into; that is,...


3

It is not possible, and if it were, it would probably be considered bad practice1. Gotos within a function make code impossible to trace by inspection; gotos across functions would make the situation much worse. Here's an example: i = 4; label: printf( "%d\n", i ); What value actually gets printed? Is it 4? Is it ever 4? I can't know until ...


4

Pick a Http library for C. Use it to call on Stack Exchange's public Web API.


3

The compiler operates under the as-if rule that allows any and all code transformations that don't change the observable behavior of the program. [C++14: 1.5/8] The least requirements on a conforming implementation are: Access to volatile objects are evaluated strictly according to the rules of the abstract machine. At program termination, all ...


1

One of the best rules of thumb in such situations is a famous phrase: "Code is read more often than it is written." You're going to write the code once. It's not that big of a deal to type a few more characters. When starting use macros, the question should be "does this make it easier for the reader to understand." The answer to that question depends ...


3

To answer your question, yes you could write a macro to accomplish the for loop. However, this is not a very good idea. As another user pointed out, this adds difficulty in understanding the program. Also, I have seen first hand where this can become a problem. I once witnessed a situation where a contractor used 4 or 5 levels of macros on top of one ...


11

Don't do this. Using macros to reconfigure the language like this is like writing in slang. One or two instances might not seem so bad to someone has to read it (including yourself) but every time you do it you make it that much more likely that the 'well what does that mean' effect happens. You're needlessly obscuring your code, adding a layer of mental ...


2

First some background ... The macros are NULL which expands to an implementation-defined null pointer constant; C11 §7.19 3 NULL typically is an integer constant 0 or (void*)0 or the like. It may have a different implementation or type - It could be ((int*) 0xDEADBEEF) as strange as that may be. NULL might be type int. It might be type void * or ...


2

C is used basically in embedded systems where using C++ is most of the time overkill and sometimes not possible. C++ is better suited for desktop applications and video games development. Most desktop apps are written in C++ (Chrome, Mozilla etc...) and the Windows OS is written in C++. For video games it is much better to use C++ since the OOP aspect of ...


3

If you really want to understand malloc internals, look into the source code. On Linux systems it is likely to be in GNU libc but there are other implementations of the C standard library (the musl-libc source code is nice to read) and of malloc (e.g. tcmalloc). Here is a very fast and simple malloc, but completely useless since always failing. Grossly ...


21

It should be noted that it is, in the case of C++, a common misconception that "you need to do manual memory management". In fact, you don't usually do any memory management in your code. Fixed-size objects (with scope lifetime) In the vast majority of cases when you need an object, the object will have a defined lifetime in your program and is created on ...


2

I've learned to classify memory issues into a number of different categories. One time drips. Suppose a program leaks 100 bytes at startup time, only never to leak again. Chasing down and eliminating those one-time leaks is nice (I do like having a clean report by a leak detection capability) but is not essential. Sometimes there are bigger problems that ...


7

With respect to C specifically, the language gives you no tools to manage dynamically-allocated memory. You are absolutely responsible for making sure every *alloc has a corresponding free somewhere. Where things get really nasty is when a resource allocation fails midway through; do you try again, do you roll back and start over from the beginning, do ...


-5

It is up to the C++ programmer to implement his/her own form of garbage collection where necessary. Failure to do so will result in what is called a 'memory leak'. It is pretty common for 'high level' languages (such as Java) to have built in garbage collection, but 'low level' languages such as C and C++ do not.


38

In C, C++ and other systems without a Garbage Collector, the developer is offered facilities by the language and its libraries to indicate when memory can be reclaimed. The most basic facility is automatic storage. Many times, the language itself ensures that items are disposed of: int global = 0; // automatic storage int foo(int a, int b) { static ...


22

C++ has this thing called RAII. Basically it means garbage gets cleaned up as you go rather than leave it in a pile and let the cleaner tidy up after you. (imagine me in my room watching the football - as I drink cans of beer and need new ones, the C++ way is to take the empty can to the bin on the way to the fridge, the C# way is to chuck it on the floor ...


94

The programmer is responsible for ensuring that objects they created via new are deleted via delete. If an object is created, but not destroyed before the last pointer or reference to it goes out of scope, it falls through the cracks and becomes a Memory Leak. Unfortunately for C, C++ and other languages which do not include a GC, this simply piles up over ...


78

C++ does not have garbage collection. C++ applications are required to dispose of their own garbage. C++ applications programmers are required to understand this. When they forget, the result is called a "memory leak".


0

The other answers lack real world examples, so I will add one. One of the reasons why I (personally) try to avoid unsigned types. Consider using standard size_t as an array index: for (size_t i = 0; i < n; ++i) // do something here; Ok, perfectly normal. Then, consider we decided to change the direction of the loop for some reason: for (size_t i =...


5

Because the C language is designed to be implementable on any platform, no matter what set of integer sizes it natively provides. In fact, none of the intN_t types are guaranteed to exist at all. Only an implementation which provides a two's complement signed integer of exactly N bits (no padding bits allowed) will define the corresponding intN_t type (see ...


0

Consider this alternative, which limits the scope of important_var to a single source file and also encapsulates all the important behavior into a c-style class. important_class.c static float important_var = 0.0; void do_important_operation(void) { math.operation(important_var); } void do_important_adjustment(float amount) { important_var += ...


3

To add to the existing answers, it's all well and good saying that you're going to choose Python or PHP for your project, because of their relative safety. But somebody's got to implement those languages and, when they do, they are probably going to do it in C. (Or, well, something like it.) So that's why people use C — to create the less dangerous ...


1

Chapter and verse: 6.3.2.3 Pointers ... 3     An integer constant expression with the value 0, or such an expression cast to type void *, is called a null pointer constant. 66) If a null pointer constant is converted to a pointer type, the resulting pointer, called a null pointer, is guaranteed to compare unequal to a pointer to ...


0

A big thing to consider is that once a language is "settled" a lot of it comes set in stone. A lot of time and resources are spent making software in that language. And in a lot of cases, once software is done, it's done and only small maintenance remains to be done. You can't sell: "hey you need to change all the software you made because we introduced ...


2

Money. Cheaper developers, faster development speeds, and less bugs equal more money. Portability. Many high level languages allow you to target different platforms out of the box. Low level languages like C require significant efforts run on multiple platforms. Training. You can train a developer in Python in a day, while something like C++ takes ...


24

"Besides the fact that a higher level language is easier to code in and therefore less error prone" I really think this is a good enough reason all by itself. If you have no compelling reason to work in a low level of abstraction (such as performance, knowledge in the team, etc), then there is no reason to do it. If all you want is a coffee, then you want ...


1

Higher lever languages are by definition easier to learn, they take away a lot of the complexities of lower level programming such as memory management. Besides that since the explosion of hardware power it is much cheaper to get a faster processor or more RAM into a machine that paying the developer hours that'd come with a more complex programming language....


4

What is "dangerous"? The claim that C is "dangerous" is a frequent talking point in language flame wars (most often in comparison to Java). However, the evidence for this claim is unclear. C is a language with a particular set of features. Some of these features may allow certain types of errors that are not allowed by other types of languages (the risk ...


1

As always, programming language is only a consequence of problem solving. You should in fact learn not just C but many different languages (and other ways of programming a computer, be it GUI tools or command interpreters) to have a decent toolbox to use when solving problems. Sometimes you will find that a problem lends itself well to something that is ...


3

I am considering learning C There is no specific reason not to learn C but I would suggest C++. It offers much of what C does (since C++ is a super set of C), with a large amount of "extras". Learning C prior to C++ is unnecessary -- they are effectively separate languages. Put another way, if C were a set of woodworking tools, it would likely be: ...


11

In C, NULL is a macro that expands either to 0 or (void*)0 (or something that has a similar effect). In the first case, you can not differentiate between NULL and 0, because they are literally the same. In the second case, your code will cause a compile error, because you can't compare an integer variable with a pointer.


-1

It depends on what you intend to do with it. C was designed as a replacement for assembly language and is the high level language that is closest to the machine language. Thus it has low overheads in size and performance and is suitable for systems programming and other tasks that require a small footprint and getting close to the underlying hardware.


5

Historical reasons. I don't often get to write brand new code, mostly I get to maintain and extend the old stuff which has been running for decades. I'm just happy it's C and not Fortran. I can get irritated when some student says, "but why on earth do you do this awful X when you could be doing Y?". Well, X is the job I've got and it pays the bills very ...


2

Allow me to rephrase your question: I am considering learning [tool]. But why do people use [tool] (or [related tool]) if [they] can be used 'dangerously'? Any interesting tool can be used dangerously, including programming languages. You learn more so you can do more (and so that less danger is created when you use the tool). In particular, you ...


3

This sounds like the old CFront compiler - which compiled C++ into C: Cfront was the original compiler for C++ (then known as "C with Classes") from around 1983, which converted C++ to C; developed by Bjarne Stroustrup. The preprocessor did not understand all of the language and much of the code was written via translations. Cfront had a complete ...


8

A fundamental difficulty with C is that the name is used to describe a number of dialects with identical syntax but very different semantics. Some dialects are much safer than others. In C as originally designed by Dennis Ritchie, C statements would generally be mapped to machine instructions in predictable fashion. Because C could run on processors which ...


0

I agree with Robert Harvey... this is not a bad approach. If you would like to see an example of "class" design in c that uses a different approach look at X11/xview/etc https://www.x.org/wiki/guide/ to see how structs are used like classes...


11

It is funny that you claim C is unsafer because "it has pointers". The opposite is true: Java and C# have practically only pointers (for non-native types). The most common error in Java is probably the Null Pointer Exception (cf. https://www.infoq.com/presentations/Null-References-The-Billion-Dollar-Mistake-Tony-Hoare). The second most common error is ...


7

Besides all the above, there is also one pretty common use case, which is using C as a common library for other languages. Basically, nearly all the languages have an API interface to C. Simple example, try to create a common application for Linux/IOS/Android/Windows. Besides all the tools that are out there, what we ended up was doing a core library in C, ...


29

Sorry to add yet another answer, but I don't think any of the existing answers directly address your first sentence stating: 'I am considering learning C' Why? Do you want to do the kinds of things C is usually used for today (e.g. device drivers, VMs, game engines, media libraries, embedded systems, OS kernels)? If yes, then yeah, sure learn C or C++ ...


0

have I just been lucky enough to not to have to worry too much about it, or am I a bad programmer? Do you care about your requirements? If performance isn't a requirement then don't worry about it. Spending any significant time on it is a disservice to your employer. To an extent performance is always a requirement. If you can hit it without thinking ...


-1

Cumulative energy use There's one answer that I always think is missing from these discussion and which bothers me a bit - cumulative energy usage. Sure, maybe it does not matter much if you write your program in a high level interpreted language, and let it run in a browser with a couple of layers of indirection, or if your loop takes 0.01 seconds instead ...


9

Because "safety" costs speed, the "safer" languages perform at a slower speed. You ask why use a "dangerous" language like C or C++, have somebody write you a video driver or the like in Python or Java, etc. and see how you feel about "safety" :) Seriously though, you have to be as close to the core memory of the machine to be able to manipulate pixels, ...


13

This is a HUGE question with tons of answers, but the short version is that each programming language is specialized for different situations. For example, JavaScript for web, C for low level stuff, C# for anything Windows, etc. It helps to know what you want to do once you know programming to decide what programming language to pick. To address your last ...


237

C predates many of the other languages you're thinking of. A lot of what we now know about how to make programming "safer" comes from experience with languages like C. Many of the safer languages that have come out since C rely on a larger runtime, a more complicated feature set and/or a virtual machine to achieve their goals. As a result, C has remained ...



Top 50 recent answers are included