Tag Info

Hot answers tagged

101

To address the question you've posted in several comments(which I think you should edit into your post): What I don't understand is how does the computer know lets when it reads a variable's value from and address such as 10001 if is an int or char. Imagine I click on a program called anyprog.exe. Immediately the code starts executing. Does this exe file ...


34

I think your main question seems to be: "If the type is erased at compile-time and not retained at runtime, then how does the computer know whether to execute code wich interprets it as an int or to execute code which interprets it as a char?" And the answer is … the computer doesn't. However, the compiler does know, and it will have simply put the correct ...


24

The "simple is better" mantra has become too much dogmatic. Simple is not always better if it complicates other things. Assembly is simple - each command is much simpler than higher-level languages commands - and yet Assembly programs are more complex than higher-level languages that do the same thing. In your case, the uniform handle type enh makes the ...


11

A 4Kline long C program is a small C program. It generally needs a few weeks or months to be written by a single person. If you are familiar with the domain of the program, you should be able to understand it entirely quite quickly, and write a tiny documentation describing the design and purpose of the original program (in particular, the communication ...


10

Historically (perhaps by rewriting parts of it), it was the contrary. On the very first computers of the early 1970s (perhaps PDP-11) running a prototypical embryonic C (perhaps BCPL) there was no MMU and no memory protection (which existed on most older IBM/360 mainframes). So every byte of memory (including those handling literal strings or machine code) ...


9

There seems to be a confusion on both sides here: using a handle approach does not requiring using a single handle type for all handles exposing the struct name does not expose its details (only its existence) There are advantages to using handles rather than bare pointers, in a language like C, because handing over the pointer allows direct ...


8

The computer doesn't "know" what addresses are what, but the knowledge of what's what is baked into the instructions of your program. When you write a C program that writes and reads a char variable, the compiler creates assembly code that writes that piece of data somewhere as a char, and there is some other code somewhere else that reads a memory address ...


7

It doesn't. Once C is compiled to machine code, the machine just sees a bunch of bits. How those bits are interpreted depends on what operations are being performed on them as opposed to some additional metadata. The types you enter in your source code are just for the compiler. It takes what type you say the data is supposed to be and, to the best of its ...


7

If they are supposed to be singletons, and you really want to do things in your (conceptual) style, you might want to use Context object. (First and foremost: apologies. C is not my native language; C++ is.) Basically, struct Context { Engine * engine; Window * window; // any other things that are considered singletons // according to ...


7

Checking array bounds like you want is implementation specific, because buffer overflow is an example of undefined behavior (and this explains why UB can be really bad). It is also an undecidable problem in general. You can easily show that statically finding (by static program analysis, e.g. of the C++ source code, without actually running the program) ...


5

Historically, C regarded memory as consisting of a number of groups of numbered slots of type unsigned char (also called "byte", though it need not always be 8 bits). Any code which used anything stored in memory would need to know which slot or slots the information was stored in, and know what should be done with the information there [e.g. "interpret the ...


5

In a well-design C program, a file-static variable is similar to a private static member of a class: It can only be accessed by functions in that file, similar to how a private static member variable can only be accessed by functions in the class in which it is defined. There is only one copy of the variable. Its lifetime is the program lifetime. An ...


4

A function that receives a pointer does not know of the length of the corresponding array. You must pass in as a parameter yourself explicitly: void myFunc(int *yourArray, size_t yourArrayLen) Once you've done that, throwing an error is trivial. Of course, this still leaves the possibility that your caller might give you the wrong length. You can't ...


4

The answer is really fairly simple: if you want safety, use something that actually provides it--and that's not C, and not raw C-style arrays. Without departing too far from the basic style of C and raw arrays, you can use C++ and an std::vector with [i] replaced by .at(i), and get bounds checking. Using std::vector instead makes most of the problems with ...


3

There are existing protocols for performing discovery of devices; it would be better to use one of these than roll your own. The leading competitors are mDNS (aka Bonjour) and SSDP (aka Universal Plug and Play). I'd suggest reading up on these, and then picking up one of the many open source implementations to start working from.


3

In C, it is not. Other languages (e.g., Lisp, Python) have dynamic types but C is statically-typed. That means that your program must know what type the data is to properly interpret is as a character, an integer, etc. Usually the compiler takes care of this for you, and if you do something wrong, you'll get a compile-time error (or warning).


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 = ...


3

Most processors provide different instructions for working with data of different types, so type information is usually "baked in" to the generated machine code. There's no need to store additional type metadata. Some concrete examples might help. The machine code below was generated using gcc 4.1.2 on an x86_64 system running SuSE Linux Enterprise ...


3

Both pre- and postfix have basically the same advantages over infix notation. The most important of these are: much easier to translate to a format that is suitable for direct execution. Either format can trivially be turned into a tree for further processing, and postfix can be directly translated to code if you use a stack-based processor or virtual ...


3

Like Basile said, 4K lines is a small program. It should be relatively straightforward for you to puzzle out what it does and how it does it.1 You said this was a simulator of some sort; I'm guessing it acts as a server or client to some other process for testing purposes. We have similar tools for testing our software - the simulator stands in for a ...


2

I would suggest to avoid using this as a formal name in C, because this is a C++ keyword. You could use e.g. self (or me or recv, or ipse -it is self in Latin) instead of this If you code your C code without using C++ keywords, you are much more likely to be able to use your code with a C++ compiler. In particular, quite often a C header file foo.h (with ...


2

if it is the same, it should look the same This is not how naming works. Your are the same however people call you. Granted, you have a name on a birth certificate, but that is not sufficient. You are John Doe, yes, but the one who lives at such and such place, who was born that year. Someone might call you son, and someone else dad, whereas I call you ...


2

Global state, including extern variables and non-const static variables in file scope or in functions can frequently be an easy solution to a given problem, but there are three issues: static makes code untestable, because static variables tend to be non-replaceable dependencies. Or in more OOP-y words: you aren't following the Dependency Inversion ...


2

Let us keep this discussion to the C language only. The program you are referring to is written in a high level language like C. The computer understand machine language only. Higher level languages gives the programmer the ability to express logic in a more human friendly way which is then translated into machine code which the microprocessor can decode ...


1

I expect in every implementation of C, the conversion happens first. The psuedo-assembly for bar: store 2 in argument-register-0 call foo store 3.1 in temporary-register-0 convert-to-int temporary-register-0 into temporary-register-1 store temporary-register-1 in argument-register-0 call foo Your optimizer is probably smart enough to eliminate ...


1

I believe that the attitude stems from a long-time philosophy to defend a C library API from abuse by beginners. In particular, Library authors know it's a pointer to the struct, and the struct's details is visible to library code. All experienced programmers who use the library also knows it's a pointer to some opaque structs; They had enough hard ...


1

I suspect the real reason is inertia, that's what they've always done and it works so why change it? The main reason I can see is that the opaque handle lets the designer put anything at all behind it, not just a struct. If the API returns and accepts multiple opaque types they all look the same to the caller and there's never any compilation problems or ...


1

The most obvious benefit of the handles approach is that you can modify the internal structures without breaking the external API. Granted, you still have to modify the client software, but at least you're not changing the interface. The other thing it does is provide the ability to choose from many different possible types at runtime, without having to ...


1

There is no way in C(++) to get the length of an array from a pointer to its first element. (There are platform-specific functions like _msize in MSVCRT, but that only works on malloced pointers.) What's typically done when passing arrays to functions is to pass the length along with the pointer so that bounds-checking can be done at runtime. void ...


1

Actually, it doesn't matter whether B->start or B->data is "evaluated" first. The result of interest is address of the referenced element, which is the sum of the base address and the product of the index and the size of the element. The two addends are independent, meaning that the order of their evaluation is irrelevant. The result of the addition is an ...



Only top voted, non community-wiki answers of a minimum length are eligible