Эмуляция выражений операторов GCC - PullRequest
0 голосов
/ 29 июня 2018

Я вынужден использовать компилятор IAR EW430 v7.12 для встроенного проекта, и он только официально поддерживает c99.

Я хотел бы иметь возможность эмулировать выражения-выражения GCC в общем виде любыми способами ДРУГОЕ, чем написание целого ряда встроенных функций.

Есть ли способ достичь этого? (возможно, используя MACRO-wizardry? Или эмулируя Lambdas, или некоторые скрытые переключатели компилятора, которые позволят это?) Очевидно, кроме изменения компилятора.

В частности, результат последнего оператора составного выражения должен содержать как его тип, так и значение, а не передаваться в качестве макропараметра.

Я искал несколько месяцев, но самое близкое, что я могу получить, - это впечатляющая впечатляющая библиотека , но это, похоже, ужасно много.

Ответы [ 2 ]

0 голосов
/ 29 июня 2018

В комментариях вы уточняете, что

Мое намерение состоит в том, чтобы действительно (или как можно ближе) подражать Заявлению Выражения, которые будут использоваться всеми возможными способами, с каждым собственность у них есть.

Поэтому давайте посмотрим, как формируются выражения операторов и что они делают:

Составной оператор, заключенный в скобки, может выглядеть как выражение в GNU C. Это позволяет вам использовать петли, переключатели и локальные переменные в выражении.

[...]

Последнее в составном операторе должно быть выражением сопровождается точкой с запятой; значение этого подвыражения служит стоимость всей конструкции.

( Документация GCC )

Для этого есть две ключевые части:

  • Конструкция построена вокруг составного оператора и поэтому может иметь в пределах всего, что может иметь составной оператор.

  • Конструкция оценивает значение.

Более того, вы прямо говорите

В частности, результат последнего утверждения соединения выражение должно нести как свой тип, так и значение, а не иметь передается как параметр макроса.

Вы загнали себя в угол здесь. Операторы C не являются выражениями, что означает, что они не оцениваются по значениям. Вот почему операторские выражения GCC являются расширением. Значения не имеют связи, и в той степени, в которой они могут рассматриваться как имеющие область видимости, они ограничены выражениями, в которых они появляются, и объектами, которые их хранят. Единственный способ передать значение из оператора - это присвоить его объекту соответствующего типа (и вы явно хотите этого не делать) или return (что требует, чтобы оно было в функции).

Существуют и другие характеристики выражений выписок, которые могли бы заинтересовать вас в первую очередь. В частности, поскольку вы подняли лямбду, я подозреваю, что вас интересует тот факт, что выражения операторов живут внутри контекста окружающего кода, так что, среди прочего, они могут использовать идентификаторы, которые там находятся в области видимости. Если это то, что вам нужно, то вам, вероятно, нужно просто написать обычные блоки кода и предоставить переменные, в которых будет сообщаться результат.

ОДНАКО, есть другая альтернатива, которая может дать вам немного того, что вы ищете. Вы можете вычислить несколько выражений по очереди, каждое из которых может использовать побочные эффекты предыдущих, используя оператор запятой. Например,

int first = 1, second = 2, temp, new_first;

new_first = (temp = second, second = first, first = temp);

В результате значения first и second меняются местами, а полученное новое значение first присваивается new_first. Конечно, это не позволяет использовать циклы, операторы if, и т. Д. , и особенно не предусматривает объявления локальных переменных, таких как temp. Как я сказал немного того, что могут делать выражения оператора.

0 голосов
/ 29 июня 2018

Я понимаю, что это не тот ответ, который вы ищете, но, поскольку вы спросили: «Есть ли способ достичь этого?», Я должен сказать, что ответ просто «Нет».

Не поймите меня неправильно - я знаю, что вы ищете, и почему вы этого хотите. Это очень крутая функция. Когда-то я пытался изобрести свой собственный C-подобный язык, и одна из моих целей состояла в том, чтобы каждое утверждение можно было использовать в качестве выражения. Но эта функция просто не является частью C, и нет достойного способа ее подражать.

На самом деле, вы можете довольно легко доказать, что не существует достойного способа эмулировать его, потому что, если бы он был, у пользователей gcc не было бы необходимости реализовывать эти сумасшедшие, нестандартные расширения.

Так что, если вы хотите использовать gcc и его расширения, обязательно используйте gcc и его расширения. Но если вы хотите писать в достаточно чистом C, вам просто придется научиться жить без выражений операторов. «Когда в Риме, делай, как римляне». Все, чего вам удастся достичь с помощью безумной макро-магии, вероятно, (а) не совсем удовлетворит ваше стремление к выражениям истинных высказываний и (б) сделает обслуживание вашей программы кошмаром для тех, кто придет после вас и не поймет, что в них такого хорошего .

Вы говорите, что выполняете встроенную работу, но уверены, что для вашей платформы нет порта gcc? (Я знаю, что вы сказали, что «вынуждены» использовать IAR, но вы также сказали, что это «игрушечный проект», так что, возможно, вы можете нарушить это правило. IAR всегда заставляет меня думать о слогане Википедии «Игнорировать все правила» в любом случае . :-))

Но так как вы сказали, что выполняете встроенную работу, это еще одна причина, чтобы не поощрять такого рода особую филяцию. У меня сложилось впечатление, что одной из определяющих характеристик «встроенной работы» является то, что она все равно пытается отрицать использование половины языка, предписывая использование только чрезвычайно четко определенного, чрезвычайно безопасного подмножества. Поэтому я сомневаюсь, что расширение, такое как выражения выражений, будет работать для вашего проекта.

...