New answers tagged

4

For C, the first edition of The C Programming Language (a.k.a. K&R) suggests that your intuition about preprocessor macros is correct: Symbolic constant names are commonly written in upper case so they can be readily distinguished from lower case variable names. In many ways, this was a holdover from assembly language, where macros were defined ...


4

At the time the C99 Standard was ratified, there already existed countless C programs that used int32 as an identifier. On platforms where both int and long were 32 bits, some of that pre-existing code would have defined int32 as int and some as long (the latter allows compatibility with platforms where int is 16 bits but long is 32; the former allows ...


3

Yes, they can, sort of. You can make use of the fact that C allows for pointers to function blocks in memory, a.k.a. function pointers and using that you may create interface like polymorphism as well as virtual functions (even if it is not that pretty). I wrote a blog post on this subject, following a question from one of my students, recently, pertaining ...


2

Its not so much that globals make code harder to debug - though if you have a very large program and global state that is defined a long way from where its used, that can have an adverse effect. The problem with global state is that its global, singular, difficult to extend. Think of this, you have some variables that you want to modify in your functions, ...


40

Structs can hold function pointers, but those are really only needed for virtual methods. Non-virtual methods in object-oriented C are usually done by passing the struct as the first argument to a regular function. Look at Gobject for a good example of an OOP framework for C. It uses macros to handle a lot of the boilerplate required for inheritance and ...


18

Your function should look like this. void replace(struct string * s, int i, char c); This accepts a pointer to the object to operate on as the first parameter. In C++, this is known as the this-pointer and need not be declared explicitly. (Contrast this to Python where it has to.) In order to call your function, you would also pass that pointer ...


7

With function pointers, you can do: str.replace(&str, i, c); This is generally only useful if the implementation can change, in which case you should use a vtable so the overhead is only one pointer per struct: str.vtable->replace(&str, i, c);


3

Modifying a variable on one thread and reading it on another is always problematic. Modifying it on two threads is worse. You can use atomic variables. An atomic variable would for example guarantee that readers get important_var = 0, then important_var = 5.0, then important_var = 10.0 and so on. If important_var is not atomic, reading it just when it is ...


1

The main problem with your malloc_quick() implemenation is, that it is not thread-safe. And yes, if you omit thread-support from your allocator, you can achieve a significant performance gain. I have seen a similar speedup with my own non-thread-safe allocator. However, a standard implementation needs to be thread-safe. It needs to account for all of the ...


1

If you compare a real malloc implementation with a school project, consider that a real malloc has to manage allocations, reallocations and freeing memory of hugely different sizes, working correctly if allocations happen on different threads simultaneously, and reallocation and freeing memory happen on different threads. You also want to be sure that any ...


3

If you care only about efficiency, here is a standard conforming and very efficient implementation: void* malloc(size_t sz) { errno = ENOMEM; return NULL; } void free(void*p) { if (p != NULL) abort(); } I'm pretty sure you won't find any faster malloc. But while still conforming to the standard, that implementation is useless (it never ...


3

First, malloc and free work together, so testing malloc by itself is misleading. Second, no matter how good they are, they can easily be the dominant cost in any application, and the best solution to that is to call them less. Calling them less is almost always the winning way to fix programs that are malloc-limited. One common way to do this is to recycle ...


6

There are multiple implementations of malloc and they can use very different algorithms. Two very widely used implementations are jemalloc and dlmalloc. In both cases the links have a lot of information about the thought process and trade-offs made in a general purpose allocator. Bear in mind a malloc implementation has very little information to go on, ...


2

I think that the two SUT are not direct comparisons. I would not be surprised at any comparable difference when you consider all the variables: memory manufacture, motherboard architecture, compiler version (that compiled malloc), what the memory space application is like on the SUT at the time, etc etc etc ....... Try using your test harness to be more ...


2

It's certainly not a bad practice to keep the library configuration elements grouped in a common configuration header. On the contrary ! It eases portability to other environments/architectures and facilitates maintenance/deployment. And the application configuration could be different from the library configuration. The only issue is to avoid name ...


1

As mentioned elsewhere, limits.h will specify the ranges allowed for each type - INT_MIN, INT_MAX, UINT_MAX, etc. If you need an integer type of a specific width, the stdint.h header provides type definitions like int8_t, int16_t, etc.


2

The C language standard does not mandate how memory gets allocated for function parameters, only how that memory should behave. It only specifies that function parameters have block scope (not visible outside the function body), no linkage (no other identifiers in the code refer to the same object), and automatic storage duration (space is allocated at the ...


0

We can classify computation in several categories. For one: A significant context for computing is some form of indexing. We can index into an array, for example. Another form is that we can count objects (e.g. give them an int id) that we create in memory. For these, our programming languages are usually implemented so that they run out of memory ...


5

It's going to allocate the space for the int on the stack, copy the value of 'num1' onto the stack, call the method and then return the value, at which point the stack is popped. Essentially you'll have a copy of 'num1' on the stack for your function to use. If you passed a pointer or a reference to 'num1' instead, then the address would be put on the ...


2

Your certainly on the right track. For my projects I use: "check" to unit test all method (including as many code paths as I can - have time for). This runs super fast and gives me confidence that the parts of my application are doing what I expect. "Valgrind" to check the memory usage of the final application while running system/regression tests. This is ...


1

How can both of these return values to original function They don't; your book is badly-worded. In the second case: average = gradeAve(grade1, grade2, grade3); gradeAve returns - literally with a return statement - its result. Here the function parameters (grade1..3) are just inputs, and the whole call looks like a mathematical expression. In the ...


0

You can use either method to return values back to the caller. However in general I'd use the following. Save the "return value" for the logical outcome of an operation. Eg, this worked, there was an error, etc. If your method want to return some computed value, send the container for that data in the request and collect the result from there. However, ...


1

I'm still very confused by this question but might as well try... In your half function, the return; statement doesn't do anything useful. If you left it out the function would behave exactly the same way. Similarly, the parentheses in return (localAverage); also do nothing and are better left out. Normally return; is only useful when you want to return ...


-1

This is best explanation I found on page 3 that any newbie can understand quickly and avoid bugs.


3

Note: 'int' is only guaranteed to be at least 16 bits. It's even smaller than you thought! If you want to guarantee at least 32-bits use 'long'. For even larger values look at things like 'int64_t' or 'long long'. How does a newbie avoid problems like this? I'm afraid it's the same as for many other programming problems. "think carefully and take care". ...


2

Limits.h stores the min and max values for integer types in C. N.B. C++ has its own version: <limits> If you're really interested in the number of bits a type uses on your platform, you can do something like this (from here): #include <limits.h> #include <stdio.h> int main(void) { printf("short is %d bits\n", CHAR_BIT * sizeof( ...


1

Generating for all possibilities did not look to be a very good solution to me. The key and values may be objects as well. Hence, the possibilities are infinite :( Did you have a look at IMapImpl class? This class does not use types but the binary data (which is provided after serialization). Hence, another solution would be writing an API that mimics this ...


0

I think google will help you with why you would want to use it https://en.m.wikipedia.org/wiki/Zero-configuration_networking#DNS-SD This is important if you can not define the path to the service ahea of time. For example if your C program is inside a printer and you want anybody on the network to be able to find the printer without knowing its IP address. ...


2

It's a management decision. Your management should be in a position to determine how much money they are making by supporting Windows 3.11. If they have any brains they will realise that customers who complain if you don't support them for free don't actually make you money. You can support them by telling them what the cost of supporting an old version is. ...


4

It's not the most basic printing function. The most basic printing functions would be puts and putchar which print a string and char respectively. f is for formatted. printf (unlike puts or putchar) prints formatted output, hence printf. For example it can print an int in hexadecimal, or a float rounded to three decimal places, or a string left padded. ...


4

I think this is more of an issue about getting virtualbox or vmware to provide access to the hosts serial port than it is about virtualization OS or even the guest OS. I would start with a host system running a modern OS (win 7/8/10 or Linux distro) with a USB to serial port adapter that is based on a real rs-232 implementation, such as the prolific pl2303. ...


17

Let's go back to the K&R roots: Origin In the tutorial chapter, on page 11 of original K&R, you'll find a hint on the origin of the function: By the way, printf is not part of the C language; there is no input or output defined in C itself. There is nothing magic about printf; it's just a useful function that is part of the standard ...


19

The function "printf" was inherited by C from the B standard library. In B it wasn't the only such function, for example there was also a "printn" for printing numbers. See a reference for the language from an early unix version here: https://www.bell-labs.com/usr/dmr/www/kbman.html


4

drivers for some of the custom hardware belonging to the solution are not compatible with later Windows This is the crux of the matter. You can recompile your legacy C program with a newer Visual Studio, fix up all the compiler warnings and errors, and generally turn an old system into an identical one that runs on Windows 7 (or later if you must) but ...


2

Most of the embedded solutions are written in C. The reason being, C is a very powerful language and the user has a lot of control on hardware. On the other hand it also helps you create abstractions, however the development has to be done by the team. This is the reasons most semiconductor companies provide C/C++ compiler with their toolset. One resorts ...


6

Most end-user applications are written in C or a close derivative of C, or another language, like Lua or BASIC or something. However, a lot of the really interesting jobs with microcontrollers require a thorough understanding of assembly, because you're writing or supporting the libraries, doing things with new parts that don't have support in a high-level ...


6

I'm not going to debug your code, there's not enough context to do this anyway, but I'm going to show you an idiom that you will probably find easier to use correctly. As a bonus, it will also be faster. Have a look at your loop body. You are allocating memory during each iteration and free it under certain circumstances depending on the overall control ...


-2

As a concrete answer for interfacing with DirectX from Go, I have created a Direct3D9 wrapper: https://github.com/gonutz/d3d9 and a DirectInput8 wrapper: https://github.com/gonutz/di8 As for your questions, these wrappers do what you asked about, they implement callbacks, e.g. for DirectInput's device enumeration, they pass Go values and void* pointers ...


1

You cannot know, and on a multi-core system both processes could run simultaneously (on different cores). (you should think as if (when fork succeeds) both parent and child are running exactly simultaneously; what is actually happening is an unimportant, and difficult to observe, implementation detail) Read wikipage on fork, then read carefully man page ...


4

The whole point of compiling in "debug mode" is that it includes debug symbols in the executable to enable the use of a debugger, at the cost of foregoing some performance optimizations that aren't possible with debug symbols. If you don't plan on running that executable in a debugger, then "being in debug mode" doesn't gain you anything. It's likely that ...


4

You are better off to make a clear distinction between "compile time debug" mode (which is what you control by #define DEBUG), and specific "debug features" which should be available even when you compile with #define DEBUG false, and could be enabled or disabled at run time. Better call the latter differently, name the features (like "logging mode", ...



Top 50 recent answers are included