开发者

How "low" does C go as a "low-level" language? [closed]

It's difficult to tell what is being asked here. This question is ambiguous, vague, incomplete, overly broad, or rhetorical and cannot be reasonably answered in its current form. For help clarifying this question so that it can be reopened, visit the help center. Closed 11 years ago.

We often hear that C is a low-level language, but how low does it go? The lowest level I am aware of is memory management using pointers. Are 开发者_开发知识库there further levels I have yet to discover? What does "close to the hardware" mean? How "close to the hardware" is C?


Use the standard terminology. Higher level languages and Lower level languages.

High level languages are designed for the ease of the person writing the language.

Lower level languages are designed for the ease of the computer running the language.

C is just a step up from assembly language, which is practically a human translation of machine code. It doesn't get any lower than machine code, but people don't read hexadecimal very well, so assembly is considered the lowest level programming language.

Most C operations can be translated into less than ten machine instructions. Some can be translated into a single machine instruction (depending on many circumstances). By comparison, many high-level languages might require dozens to thousands of machine instructions to implement a particular operation.

The "level" of a language is mostly an abstract concept. It is not useful for much except comparing one language to another in the context of trying to understand if you will have to write more source code in one or another, or if you will have to know more about the machine's architecture in one language as compared to another.


C is sometimes referred to as "portable assembly language". Essentially anything that you can do in assembly, you can do in C (either through features built into the language or through inline assembly).


C is little more than a procedural wrapper around ASM. A good C programmer, who knows what's behind that language, should be able to look at a code snippet and write out the ASM that the code would compile into. Those ASM instructions can be translated 1:1 to binary machine instructions. It's pretty much one step above assembly, and as such you can write C code that does ANYTHING the computer is capable of, BUT, being at such a low level, it is relatively primitive in terms of what you have to be specific about. For instance, memory is treated as such, and not abstracted into constructs like the "heap". Creating a "new" object in an OO language is as simple as saying so; the equivalent C code would involve a malloc for the sum of the size of all the members of that object, and pointers to each of the object's members within the block.


A person who creates hardware (cpu, motherboard, etc) also provide its machine language (assembly language). That becomes the lowest level itself. Then some other person writes a compiler for C which converts C syntax into native assembly language for that hardware (please correct me if I am wrong). With C you can use assembly hence lowest level reached!!


The memory you can manage on general purpose OS' are usually virtual memory, so it usually all a fraud - your C pointers doesn't contain the physical memory addresses, there's a whole layer deeper than that.

Getting below that requires you to program the MMU , which isn't easily done in C, it usually requires some very architecture dependant assembly and your code would need to run in some form of privileged mode(as the OS kernel does)

There might also be various other co-processors or whole range of instruction sets it can be hard to get at directly in C.


The definition of 'low' is a bit difficult, but C supports an number of system calls, gotos, and even assembly mixing through extensions.


You need to define what you mean by low level in order to answer this question.

C lets you do kind of everything you could do with assembly, but well not everything. If you want to do something weird/particular/unusual you could need to use assembly, although for most(/all?) real purposes C will be more then enough, assuming you've got a good compiler for your hardware.


EDIT: Elaborating this a little further...

C doesn't give you any guarantee about the assembly instruction it will be compiled into, and only gives some partial indications about objects will be allocated in memory.

In general If you need to have stuff in memory in a particular way, of if you need a particular sequence of assembly instruction to be ran, you'll probably have to use some other language (probably assembly directly), otherwise in general C will be fine.

Of course we can find as many special cases as we want to: if your has got some special assembly operations that let you do fancy high level stuff, C won't probably be able to exploit these.

C has been thought to replace assembly on normal (maybe I could say general purpose) processors, it won't be ideal on processors with a native functional assembly or in many other contexts.


You cannot just say "how level is C?", you need to do the opposite: define what kind of low level stuff you need and then see if C is able to do that.


How about register? A keyword on a local variable declaration that asks the compiler to store it in a CPU register - though it may ignore your suggestion.

However, GNU C extends this to the point where you can specify a particular register you'd like to use!

register int foo asm ("a5");


The main thing that C obscures, to the extent that it obscures anything at all, is flow control, in a few edge cases. The only thing I've ever written in assembly that didn't translate well to C involved hopping into a block of code at an arbitrary point, having it execute from that position, periodically checking a certain status condition and upon finding the need, storing the current program location somewhere and exiting. Then next time, I jumped back in at the same position as that block of code last exited. Co-operative coroutines, I guess you'd call them.

The C solution was to use two separate threads, communicating via semaphores. But threads aren't part of the C language itself.


C today is used in many cases as a "portable assembly language" because the semantics of the language can be pretty much just a thin veneer above the underlying machine architecture.

In the past, it was fairly straight forward to look at lines of C code and have a good idea what the actual machine language would be that the C code would generate.

When taken in it entirety along with its surrounding development environment, it is straightforward to have perfect control over memory layout of data structures and overall memory placement. Mind, this kind of C code is, as a whole, non portable as it relies on implementations details of the compiler that the C standard allows to be flexible and implementation based. But in the large, the C code itself can be MOSTLY portable. This is aspect of the language is what led to its popularity in such systems as Unix in allowing the bulk of the OS to be portable across machines with as little implementation specific aspects of an implementation being in, say, assembly language, as possible.

Today, with modern compilers and their optimizations, C can be less literal. What you see in the C code may not be translated literally in to what you get in the assembly because of the actual optimizations made by the compiler.

A simple contrived example is something like:

int func(int a, int b) {
    int c;
    int d;

    d = 10;
    return a * d;
}

In a simple compiler, an implementation may well allocate 4 int's on the stack, 2 for the arguments, and 2 for the work variables. An obvious optimization is to not allocate the 'c' variable at all, as it is unused. A further optimization is to ignore 'd' as well, and simply use the constant 10. And even smarter compiler may well see how this func is being used and inline it automatically in the calling function, eliminating the subroutine call completely.

So, on the one hand you can see the code and say "this is what it will look like in assembly", and thus treat it as a low level wrapper on top of assembly. On the other, you can turn the modern compilers optimizations up so that they are less literal, thus keeping the semantics of what you're expressing in code, if not the actual perfect implementation.


What I mean by low level is what everybody means when they say C is a low-level language. If I knew that I wouldn't have to ask the question. – ecounysis 27 secs ago

Thats not what the question looked like at all.

If what you want to know is what "low-level" means when they say that, wiki has articles you may want to read.

http://en.wikipedia.org/wiki/Low-level_programming_language

http://en.wikipedia.org/wiki/High-level_programming_language

When they say C is a low-level language they aren't talking about any degree. Either a language is higher level or low level. They are two different types or Categories.


The fact that you ask this question expresses your naivete of the subject. It's just not that simple.

In the end- C does not have the complete flexibly of a assembly language, but it comes close. It's missing features such as Tail Recursion

But for most purposes, C does everything you would -probably need-

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜