Що зупиняє C від компіляції / інтерпретації / JIT'ed?


9

Яву часто хвалять за свою дивовижну портативність, яку, я вважаю, є завдяки JVM. Моє запитання полягає в тому, що перешкоджає компілюванню / інтерпретації / JIT'ed .., якщо це так, C також можна написати один раз і змусити його працювати на будь-якому пристрої, який у вас є. але це не популярний механізм обробки програми С.

Які недоліки обробки C таким чином, а також які переваги обробки Java таким чином, а не компіляція до машинного коду, крім переносимості звичайно?


Тут вже є дуже хороші відповіді на ваше запитання: stackoverflow.com/questions/3925947/…
Doc Brown

2
@delnan, я можу сказати, що "те, що зупиняє C від компіляції / інтерпретації / JIT'ed", дійсно втрачає своє значення, коли мова може орієнтуватися на віртуальну машину, яка має JIT, або ситуації, коли vm виявить відсутні апаратури в апараті та перекомпілює код, щоб відповідати наявному апаратному забезпеченню (наприклад, з OpenGL (написано на С) на OSX для різних графічних карт). Ні, ви не можете захопити щось складене для націлювання на llvm на одній машині та запустити його як таке на іншому процесорі. Але складений / інтерпретований / рядок JIT може бути досить розмитим.

1
Часто Java обробляється через дивовижну портативність. Це портативно для систем, де було складено JVM, тобто систем, для яких було складено JVM (написано на С). Немає нічого, що не заважає керувати кодом C однаково, за винятком того, що ніхто не бачить достатньої користі від цього, щоб виправдати зусилля.
Піт Бекер

2
Мене спантеличує цей біт: "що не дозволяє компілювати C / [...]". А, нічого?
Андрес Ф.

1
C-компілятори в наші дні досить швидкі, тому "make myprog.c; myprog", ймовірно, працює швидше, ніж більшість перекладачів.
Джеймс Андерсон

Відповіді:


18

C - це те, що я б назвав мовою середнього рівня. Її мета - виконувати функцію "асемблера дуже високого рівня", саме тому він працює так добре, як ціль компілятора, і чому він так добре підтримує портативність.

Історично історичні перекладачі зазвичай використовувались з мовами високого рівня в контексті викликів методів. У своїй найпростішій формі інтерпретатор просто аналізує кожне ключове слово в мові джерела разом із пов'язаними маркерами та перетворює це у виклики методу та параметри. На практиці більшість перекладачів робить перетворення мови-джерела в якесь проміжне подання, і саме таке представлення інтерпретується.

Що зупиняє C від інтерпретації чи джитінгу? Нічого. Але це не є причиною розвитку С.


6

Перш за все, варто відзначити, що JVM Sun написаний на C. C - дуже популярна мова, коли потрібна портативність.

C мову є переносним , хоча багато C програма не є. Це відбувається тому, що C не встановлює стільки обмежень для програміста або робить стільки припущень. Якщо програміст C хоче, щоб його програми були портативними, він повинен покласти ці обмеження на себе.

На практиці це насправді не набагато складніше, ніж жити з обмеженнями, які силами Java на вас. Це здебільшого питання пам’яті про свою витривалість та примітивні розміри, а також використовувати портативні бібліотеки типу GTK + замість бібліотек для платформи.

Ви можете зробити компілятор GTK + target та C, який підтримує віртуальну машину, навіть, можливо, JVM, і отримати існуючий код для роботи з дуже невеликими змінами. Насправді, без збору сміття віртуальна машина С могла б бути набагато простішою. Чому б ти хотів цього зробити?

Зворотний, компілюючи Java до рідного коду, також можливий. Це в основному те, що робить JIT. Чому б ти хотів цього зробити? Я впевнений, що існують проекти для домашніх тварин, щоб зробити це "просто тому", але вони не використовуються серйозно.


5

Ти сказав:

Яву часто хвалять за свою дивовижну портативність, яку, я вважаю, є завдяки JVM.

І там, у першому реченні, ви помиляєтесь. Java не є портативною через JVM. Java є портативною, оскільки мова Java визначена таким чином, що не залишає реалізатора жодної свободи в тому, як може поводитися програма.

Як приклад, у Java є два типи "int" (підписане 32-бітове ціле число) і "long" (підписане 64-бітове ціле число). C і C ++ мають "int" (підписаний принаймні 16 біт), "long" (підписаний принаймні 32 біт) і "long long" (підписаний принаймні 64 біт). Це тому, що C повинен працювати на багатьох різних процесорах і дозволяє їм поводитися по-різному.

C міг визначити фіксовані розміри для цих типів. Якби це було, то 36-бітні процесори не могли б реалізувати мову С. І вони справді не можуть реалізувати Java! Тому C дозволив мові працювати з різними комп'ютерами. Неминуче, що це дозволяє створювати код, який не є портативним. Це питання мови.


Можливо емуляцію 32-розрядної арифметики на 36-розрядній машині І ІНТЕРНЕТ результат кожної операції з 0xFFFFFFFF для вкорочення її до 32-біт. Отже, ці машини могли реалізовувати Java, це було б просто повільніше, ніж якби Java дозволяла типів на основі ненет.
dan04

4

Java дуже портативний, оскільки мова націлена на віртуальну машину Java, яка, як випливає з назви, не є справжньою машиною . Оскільки ви можете реалізувати Віртуальну машину в архітектурі багатьох різних типів реальних машин, програма на базі JVM дуже портативна.

З іншого боку, C спеціально розроблений для роботи з реальним обладнанням, оскільки він був створений для конкретної мети реалізації операційної системи, яка потребує повного доступу до обладнання. Це означає, що C-код не є особливо портативним за конструкцією , і при перенесенні програми C з однієї платформи на іншу, різні частини, характерні для цільової архітектури, потрібно буде переписати в тій чи іншій мірі.


7
C дуже портативний. Вам просто потрібно перекомпілювати на цільовій платформі і уникати тих кількох бітів, які спеціально і навмисно не є портативними.
Роберт Харві

5
@RobertHarvey: ... такі речі, як основні, як розмір різних примітивів? ;)
Мейсон Уілер

2
Так, ті речі. Прикро, що проблема існує, але мова є повністю портативною в будь-який інший спосіб, і є способи переконатися, що примітивні розміри працюють на всіх платформах.
Роберт Харві

3
@RobertHarvey: Я б сказав, що C дає можливість писати портативні програми, але це не робить це по суті просто.
Док Браун

2
@RobertHarvey: ти хочеш розпочати релігійну війну? ;-) Моя улюблена портативна мова - Python.
Док Браун

3

Насправді є інтерпретовані версії C , але вони, як правило, використовуються для швидкого експерименту, а не виробничої системи.

Вони не звичайні, бо врешті-решт, навіщо ти страждаєш від усіх С ідіосинкразій, якби не отримати невеликий, швидкий та статичний виконуваний файл?


3

Теоретично і C, і Java можуть бути компільовані до рідного коду, інтерпретуватися або компілюватися у віртуальну машину.

Технічна причина того, що C не компілюється у віртуальну машину, полягає в тому, що стандартної віртуальної машини C просто немає .

І, схоже, ніхто не хоче визначати віртуальну машину С або навіть компілювати на віртуальній машині Java (що цілком можливо). Можливо, тому, що ніхто, хто використовує C, не хоче втратити його неперевершену швидкість. Можливо, тому, що C є найсильнішим у спільноті з відкритим кодом, який може легко робити портативність шляхом компіляції (розповсюджувати та перекомпілювати джерело та виконувати), тому вони не відчувають такої потреби у переносимості виконання (розповсюдження та виконання двійкового) як закритого типу розробник джерела.


1

Власне, це і робиться. Є основні компілятори, які підтримують компіляцію до LLVM (я знаю, що "Кланг" робить, і я вважаю, що gcc також працює). Цей LLVM може бути JIT'd так само, як код Java збирається в байт-код, який є JIT'd.

Однак те, що робить java "крос-платформою" порівняно з C, це те, що Java має велику бібліотеку виконання, яку перенесли на багато платформ. C явно не дотримується цієї парадигми.


C з POSIX може бути досить портативним (до будь-якої системи POSIX), якщо ви ставитеся з обережністю.
Базиль Старинкевич

0

Існують деякі основні відмінності між Java та C. Java ізольована від операційної системи через віртуальну машину Java (JVM). JVM віддаляє операційну систему від програми. Програма java може запитати JVM про шматок пам'яті, а потім JVM запитує ОС для цієї пам'яті. Існує багато спільних технологій для різних платформ / операційних систем. JVM - це те, що дозволяє одній і тій же програмі java працювати на різних платформах.

З C немає ізоляції ОС. Програми C (як правило) працюють безпосередньо над ОС, здійснюючи прямі дзвінки в ОС. Це робить зв'язок програми C з певною операційною системою / платформою. Будь-яка нетривіальна програма збирається телефонувати в операційну систему. Крім того, програми C складаються в машинний код, який є специфічним для обладнання. Скомпільовану програму C для x86 неможливо безпосередньо запустити на процесорі ARM.


1
Java компілюється в платформно-агностичний байт - код, який може бути (теоретично, принаймні) виконаний будь-яким JVM на будь-якій платформі. C компілюється в мову складання для будь-якого процесора, на який ви орієнтуєтесь (тому якщо ви орієнтуєтесь на архітектуру x86, компілятор C створить асемблер x86 або асемблер amd64, якщо ви орієнтуєтесь на цю архітектуру, або асемблер ARM тощо). Потім мова складання перетворюється на об'єктивні файли (двійковий асемблер, справді), які пов'язані у виконуваний файл (декілька різних форматів, залежно від цільової машини).
Крейг

1
У специфікації мови Java нічого не сказано про JVM, а насправді існують Java без JVM. На Android, Java-програмах, що працюють на Dalvik VM (тепер застарілий) або Android Runtime, є реалізація Java для CLI, реалізації, що компілюються в ECMAScript, та реалізації, що компілюються у нативний код. Є компілятори C, які компілюються в JVM. Є компілятори C, які компілюються в ECMAScript. Є перекладачі С.
Йорг W Міттаг
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.