Tag Info

New answers tagged

1

For the most part, the "usual" documentation would apply, as with any other project. For the ports and bit fields, I find a table based approach to be the best. The table has a column for each bit and a description column. In each row, the bit combinations are laid out, typically using 1 or 0 and the don't care with a - or blank, the description describes ...


3

"Undefined behaviour might cause the compiler to rewrite code" has happened for a long time, in loop optimisations. Take a loop (a and b are pointer to double, for example) for (i = 0; i < n; ++i) a [i] = b [i]; We increment an int, we copy an array element, we compare with a limit. An optimising compiler first removes the indexing: double* tmp1 = ...


2

It has always been the case in C and C++ that as a result of undefined behaviour, anything can happen. Therefore it has also always been the case that a compiler can make the assumption that your code doesn't invoke undefined behaviour: Either there is no undefined behaviour in your code, then the assumption was correct. Or there is undefined behaviour in ...


4

Undefined behavior is used in situations where it is not feasible for the spec to specify the behavior, and it has always been written to allow absolutely any behavior possible. The extremely ultra-loose rules for UB are helpful when you think about what a spec conforming compiler must go through. You may have sufficient compiling horsepower to emit an ...


0

This is because there is a bug in your code: uint32_t blah(uint32_t x, uint32_t y) { if (y != 0) { foo(y); return x; ////// missing return here ////// } return rotateleft(x, y); } In other words, it only jumps the causality barrier if the compiler sees that, given certain inputs, you are invoking undefined behavior beyond ...


0

The iterator approach mentioned by Useless is pretty good, though it may be enhanced by having the "read more" function allow the caller to indicate how many items it is ready to accept. A limitation with that approach is that it may not be possible for a method to return a "snapshot" without tying up resources which could be left dangling if the caller ...


1

The designers of C wanted to make the compiler as simple as possible. While it would have been possible to handle I/O in much the fashion of other languages, and require that the compiler automatically supply the I/O routine with information about the types of passed parameters, and while such an approach might in many cases have allowed for more efficient ...


1

JavaScript is a horribly poorly designed language, with a whole bunch of weird gotchas. I would avoid it as a first teaching language. I'd also avoid C. I think it's complexity and opacity hides the concepts you're going to want to concentrate. I'd prefer Python. It's high level enough to make it easy to focus on core concepts, has some high quality ...


-2

Not a good Idea. Since you dont have the type system in JavaScript. Your students will never know why there are 3 different levels of int float and double


0

I think it depends on how rigorous you want to be with your intro courses, Khan Academy has a programming section that uses Javascript to teach programming concepts and it works pretty well because you hand wave quite a few things to start doing 'cool things' (that are generally handled by external frameworks or HTML5 APIs) and learn the basics of variables, ...


3

I would advise you to stuck to: "Start simple. Build complexity on top of it." JS with its prototype based inheritance is just to complex to begin with it. IMHO a good programming class should start low-complexity, low-level (C-console - as you already do - for example) and slowly move up to high complexity, high-level (C++ OOP, JS, PHP, etc.) - if ...


8

It all depend of the purpose of the course. If the goal is to teach programming fundamentals, consideration about actual usefullness of the language should be largely ignored. Javascript is nice because it is used in browsers. On the other hand it has a lot of problems that will distract your students from the core message of your course. Learning ...


10

I think JavaScript is not the best language to start learning programing concepts, mainly because of its "unusual" prototype approach. C is meanwhile completely there were assembler was in earlier days. So I think not very interesting for most of the students. Where I think C++ now took the role of C. But I think C++ is not that interesting or fancy for ...


0

What matters the end-user? Performance Features / Functionality Design Case 1: Optimized bad code Hard maintenance Hardly readable if as an open-source project Case 2: Non-optimized good code Easy maintenance Bad user experience Solution? Easy, optimize performance critical pieces of code e.g.: A program that consists of 5 Methods, 3 of them ...


0

You can write ugly code that is very fast and you can also write beautiful code that is as fast as your ugly code. The bottleneck will not be in the beauty/organization/structure of your code but in the techniques you chose. For example, are you using non-blocking sockets? Are you using single-threaded design? Are you using a lock-free queue for inter-thread ...


4

No reason why not... people embed Lua in C++ engines all the time, and sometimes JS engines. This enables them to run script-based code (eg for games, levels can be described in script). However, it does raise a large level of additional complexity that may not be needed if all you want to do is parse JSON. For that get a JSON library for C instead (Spirit ...


1

"replacing directory_a with directory_b" is the thing to do, but that doesn't mean you need to use regexes. Standard string manipulation functions will suffice. Depending on how the path is constructed, you may need to confirm that "directory_a" is a prefix of the path, for which there isn't a standard C or POSIX function. It sounds like this won't be ...


0

I would recommend using some existing JIT library, like GCCJIT, libjit, LLVM, asmjit, ... You could even consider translating your bytecode to C, dynamically compiling that C code into a shared library at runtime, and dlopen-ing that plugin etc... You'll need to understand some compilation and optimization techniques to do so (in particular because your ...


2

You're right that method 2 won't give you a huge performance boost over a simple bytecode interpreter loop. The real gains are to be made by using method 1. That said, method 1 isn't as hard these days as it used to be, as there are libraries that can help. One interesting approach that should be relatively east and might give good performance is to use ...


4

The order in which bit fields are placed in an integer is independent of the order in which bytes are placed in an integer. Both are implementation details. That is generally not a problem, because memory is only byte addressable, and all hardware preserves the value of a byte during transmissions. Yet, while bit and byte ordering are theoretically ...


4

A typical use case (in hosted user-code applications) to cast some pointer to an intptr_t (from <stdint.h> standard C99 or C11 header) is to compute some hash code on that pointer: uint32_t hash_of_foo_ptr(struct foo_st*foo) { return (uint32_t) (((intptr_t)foo)*613) ^ ((intptr)foo%51043)); } For historical reasons (e.g. Linux came before C99), ...


2

Of course malloc() could return a fully typed pointer. The problem is, of what type? If it returned an int*, it would make you happy, but it would not make me happy, because I want a char* instead. Clearly, we could not both have it our way. So, void* is a good baseline which does not take anyone's side.


9

Because it can't. How would it return a fully typed pointer? C doesn't have templates/generics, and it doesn't allow function overloading; let alone overloading by return type only. So there's no mechanism to have a malloc that knew what type you wanted. I've read here that in older C compilers the type of pointer returned by these functions was char* ...


0

I'm presuming that your focus is on initialization via output parameter vs. initialization via return, not the discrepancy in how construction arguments are supplied. Note that the first approach could allow Foo to be opaque (although not with the way you currently use it), and that's usually desirable for long-term maintainability. You could consider, for ...


1

One argument in favor of the "output-parameter" style is that it allows the function to return an error code. struct MyStruct { int x; char *y; // ... }; int MyStruct_init(struct MyStruct *out) { // ... char *c = malloc(n); if (!c) { return -1; } out->y = c; return 0; // Success! } Considering some set of ...


1

Depending upon the contents of the structure and the particular compiler being used, either approach could be faster. A typical pattern is that structures meeting certain criteria can get returned in registers; for functions returning other structure types the caller is required to allocate space for the temporary structure somewhere (typically on the ...


18

Both approaches bundle the initialization code into a single function call. So far, so good. However, there are two issues with the second approach: The second one does not actually construct the resulting object, it initializes another object on the stack, which is then copied over to the final object. This is why I would see the second approach as ...


22

In the 2nd approach you will never have a half-initialised Foo. Putting all the construction in one place seems a more sensible, and obvious place. But... the 1st way isn't so bad, and is often used in many areas (there's even a discussion of the best way to dependency-inject, either property-injection like your 1st way, or constructor injection like the ...


3

prefix trie: It's a degenerate DFA without cycles. For implementation you have a int state and a int nextState[256] for each state. For Matching states you would make the state number for it negative so you know when it's reached.


2

In principle a search Trie is what you want, but you'd have to profile your actual data to find out when that actually performs better (it might always be worse unless you can find a cache-friendly layout). Edit based on comments: Are you matching a stream or discrete packets? If the former, and you need to handle matches spanning the boundary between ...


2

An external function can (in C) be declared locally, inside some function, or even some block; e.g. void myfunction(int x) { extern void exit(int); if (x==42) exit(23); So you don't need any #include -d header to declare some external function - and later call it -, but that is a lot more convenient. Hence no headers are needed to call any ...


3

C assumes that undeclared functions take an arbitrary number of arguments and return an int. Undefined typedefs and structs should always cause an error. My guess would be that one of the files you do include contains the necessary include directive for this library. Most compilers support an option to print out which headers they include as they go through ...


0

The reason for using prefixes is that they let you determine immediately whether an identifier refers to a local, global, static, or member variable. Not being able to do this makes code hard to read and hard to write without bugs. However, member variables only have this problem if you use them within member functions. If you didn't do that (or if you ...


2

As others commented, this i=2+2*i++; is undefined behavior. Please read the wikipage explaining it. See this answer to understand a bit more about UB. Then read Chris Lattner's blog entries What Every Programmer should know about Undefined Behavior. To understand the actual behavior of your buggy C program, you need to dive into implementation details ...


1

3 things are happening: The value of i is being read into a register, call it R 2+2*R is being stored into i R+1 is being stored into i. The tricky thing is that you are not guaranteed that #2 will happen before #3, or that #3 will happen before #2. This is an example of undefined order of operations.


2

Because all identifiers ending with _t are reserved for future additional types. The int32_t family of types was added in the C99 standard, so they used the reserved names to avoid conflict with already existing software. You can find a nice overview of reserved names in the glibc documentation. Note: Since Microsoft is not the C standards committee, ...


0

size_t is read as 'size type' _t usually means type, and sometimes typedef. Why wasn't the type just called int32 So it could be distinguished from a built in type, stdint.h is supposed to choose the proper built in type to be the given size depending on the platform. N.b. some compilers int32_t aliases a compiler specific notation like i_32 or ...


3

The _t data types are typedef types in the stdint.h header, while int is a built-in fundamental data type to C. The _t datatypes are only available if stdint.h exists. The fundamental data types like int, however, are guaranteed to exist. Basically, it really doesn't mean much of anything. It's just how C decided to name things.


0

The issue seems to be similar to writing test cases with good code coverage There are tools for automatic test case generation that are based on code analysis. Here is a link to a paper on a tool for C programs: Klee paper (also as pdf) The tool generates test input data that is supposed to cover different branches in the code. I never worked with it, ...


24

sizeof(a)/sizeof(t) explicitly codes the type into the expression. You now have the type specified in multiple locations, with no compiler support for ensuring that you're using the same type. So, if you change the base type of the array, but not in the count expression, bingo: your element count is wrong. If you're lucky your program will crash, but if not ...



Top 50 recent answers are included