Ngoài mã máy, không có ngôn ngữ lập trình nào tồn tại trực tiếp trên phần cứng, theo nghĩa là bạn không thể cung cấp cho nó văn bản nguồn theo nghĩa đen. Tất cả các triển khai thực tế phải dịch chương trình nguồn sang ngôn ngữ của "máy".
Đối với một số triển khai, nó được dịch tĩnh. Chúng tôi thường gọi những triển khai này là "biên dịch". Đối với những người khác, nó được dịch sang một số hình thức trung gian, sau đó được dịch động khi chương trình được chạy. Chúng tôi thường gọi những triển khai này là "diễn giải". Có rất nhiều khả năng giữa những điều này và thậm chí nhiều CPU hiện đại thực hiện dịch động như một phần của lõi thực thi của nó.
Ngay cả khi chương trình của bạn được biên dịch tĩnh từ lâu trước khi thực thi, trừ khi bạn đang viết chương trình cơ sở, hiếm khi mã được biên dịch chạy trực tiếp trên kim loại trần mà không có gì hỗ trợ. Hệ điều hành cung cấp một máy ảo cho các chương trình không gian người dùng, thường cung cấp các tính năng như ảo ảnh rằng bạn có một CPU cho riêng mình. Ảo tưởng về một không gian bộ nhớ phẳng có thể lớn hơn RAM vật lý được gắn vào máy thậm chí còn được gọi là "bộ nhớ ảo".
Trên hết, ngay cả khi bạn đang lập trình trong C, vẫn có một máy ảo C! Theo truyền thống, nó được gọi là "thời gian chạy C" hoặc viết tắt là CRT.
Do C chủ yếu được dịch trực tiếp sang mã máy lắp ráp / trước thời hạn (trên một số nền tảng, cũng có thể có một số mã luồng và có thể được coi là một phần của máy ảo), nên máy ảo thường chỉ phải xử lý khởi động và tắt.
Khởi động thường bao gồm thiết lập ngăn xếp và đống; hệ điều hành hiếm khi cung cấp những thứ này cho bạn và đó là công việc của ngôn ngữ lập trình để cung cấp chúng cho lập trình viên. Trên một số nền tảng có thể có một số khởi tạo xử lý tín hiệu, thiết lập luồng "chính" trong môi trường đa luồng, chạy các hàm tạo toàn cầu trong trường hợp chương trình được liên kết với mã C ++, xử lý các thư viện được liên kết động hoặc ở đó có thể là một số xử lý cần thiết để thiết lập argc / argv và envp. Cuối cùng, CRT chuyển điều khiển sang chính.
Đối với tắt máy, nhiều hệ điều hành có thể giết chết một quá trình một cách không sạch sẽ, vì vậy tắt máy không cần phải làm gì nhiều. Điều chính là xử lý các lệnh gọi atexit () cho trường hợp chương trình thoát ra một cách sạch sẽ.