Asm ключевое слово в качестве идентификатора имени в C? - PullRequest
0 голосов
/ 11 декабря 2018

Я видел проект , который использует ключевое слово asm в качестве имени переменной, и код прекрасно компилируется с предоставленным Makefile на Linux:

int
main(int ac, char *av[])
{
    struct TMap *tm;
    FILE *inf, *hf;
    char *f, *sep;
    int c, asm; // <---

    asm = Defasm;
    // ...
}

Вот все Makefile:

BIN = qbe

V = @
OBJDIR = obj

SRC      = main.c util.c parse.c cfg.c mem.c ssa.c alias.c load.c copy.c \
           fold.c live.c spill.c rega.c gas.c
AMD64SRC = amd64/targ.c amd64/sysv.c amd64/isel.c amd64/emit.c
ARM64SRC = arm64/targ.c arm64/abi.c arm64/isel.c arm64/emit.c
SRCALL   = $(SRC) $(AMD64SRC) $(ARM64SRC)

AMD64OBJ = $(AMD64SRC:%.c=$(OBJDIR)/%.o)
ARM64OBJ = $(ARM64SRC:%.c=$(OBJDIR)/%.o)
OBJ      = $(SRC:%.c=$(OBJDIR)/%.o) $(AMD64OBJ) $(ARM64OBJ)

CFLAGS += -Wall -Wextra -std=c99 -g -pedantic

$(OBJDIR)/$(BIN): $(OBJ) $(OBJDIR)/timestamp
    @test -z "$(V)" || echo "ld $@"
    $(V)$(CC) $(LDFLAGS) $(OBJ) -o $@

$(OBJDIR)/%.o: %.c $(OBJDIR)/timestamp
    @test -z "$(V)" || echo "cc $<"
    $(V)$(CC) $(CFLAGS) -c $< -o $@

$(OBJDIR)/timestamp:
    @mkdir -p $(OBJDIR)
    @mkdir -p $(OBJDIR)/amd64
    @mkdir -p $(OBJDIR)/arm64
    @touch $@

$(OBJ): all.h ops.h
$(AMD64OBJ): amd64/all.h
$(ARM64OBJ): arm64/all.h
obj/main.o: config.h

config.h:
    @case `uname` in                               \
    *Darwin*)                                      \
        echo "#define Defasm Gasmacho";        \
        echo "#define Deftgt T_amd64_sysv";    \
        ;;                                     \
    *)                                             \
        echo "#define Defasm Gaself";          \
        case `uname -m` in                     \
        *aarch64*)                             \
            echo "$define Deftgt T_arm64"; \
            ;;                             \
        *)                                     \
            echo "#define Deftgt T_amd64_sysv";\
            ;;                             \
        esac                                   \
        ;;                                     \
    esac > $@

install: $(OBJDIR)/$(BIN)
    mkdir -p "$(DESTDIR)/$(PREFIX)/bin/"
    cp $< "$(DESTDIR)/$(PREFIX)/bin/"

uninstall:
    rm -f "$(DESTDIR)/$(PREFIX)/bin/$(BIN)"

clean:
    rm -fr $(OBJDIR)

clean-gen: clean
    rm -f config.h

check: $(OBJDIR)/$(BIN)
    tools/test.sh all

check-arm64: $(OBJDIR)/$(BIN)
    TARGET=arm64 tools/test.sh all

src:
    @echo $(SRCALL)

80:
    @for F in $(SRCALL);                       \
    do                                         \
        awk "{                             \
            gsub(/\\t/, \"        \"); \
            if (length(\$$0) > $@)     \
                printf(\"$$F:%d: %s\\n\", NR, \$$0); \
        }" < $$F;                          \
    done

.PHONY: clean clean-gen check check-arm64 src 80 install uninstall

Мне интересно, как добиться того, чтобы компилятор разрешил asm в качестве имени переменной (игнорируя тот факт, что это плохой стиль для этого).Я попытался перенести Makefile на CMakeLists.txt, но компилятор выдал ошибку из-за неправильного использования asm.Как это исправить без изменения кода?Я уже установил стандарт C99, как и Makefile, и использовал те же флаги C компилятора, но это не помогло:

cmake_minimum_required(VERSION 3.10.2)
project(qbe C)

set(CMAKE_C_STANDARD 99)
set(CMAKE_C_FLAGS "-Wall -Wextra -std=c99 -g -pedantic")

include_directories(amd64)

add_executable(qbe
        amd64/all.h
        amd64/emit.c
        amd64/isel.c
        amd64/sysv.c
        amd64/targ.c
        alias.c
        all.h
        cfg.c
        copy.c
        fold.c
        gas.c
        live.c
        load.c
        main.c
        mem.c
        ops.h
        parse.c
        rega.c
        spill.c
        ssa.c
        util.c)

Я хочу использовать CMake из-за IDE поддержка.

Ответы [ 2 ]

0 голосов
/ 11 декабря 2018

asm - это , а не ключевое слово стандарта C или зарезервированный идентификатор, хотя стандарт распознает его как общее расширение .Кроме того, в стандарте отмечается, что

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

Это в Приложении J ,который является ненормативным, но он просто суммирует вывод, который можно сделать из нормативного текста.Таким образом, соответствующая реализация не будет отклонять код на том основании, что она использует asm в качестве идентификатора.

Я считаю, что GCC, например, допускает использование asm в качестве идентификатора при любом строгом соответствииИспользуемые им режимы используются (-std=c89 или -std=c99 или -std=c11), но по умолчанию отклоняются с ошибкой или с специально включенными расширениями GNU (например, с -std=gnu11).Если вы используете другой компилятор, вам нужно будет обратиться к его документации, чтобы узнать, как получить соответствие стандарту в этой области, если это действительно возможно.

Приложение

Какпочему ваша попытка CMake не удалась, свойство CMAKE_C_STANDARD не делает то, что вы, кажется, думаете.Он сообщает CMake, если возможно, выбирать параметры компилятора, которые предоставляют функции указанной версии стандарта C, но не запрашивает строгое соответствие этому стандарту.В документах специально постулируется, что в некоторых случаях используется опция -std=gnu11, и эти или аналогичные включающие опции будут иметь эффект, противоположный тому, что вы хотите.

0 голосов
/ 11 декабря 2018

asm не является стандартным ключевым словом C.Соответствующий компилятор C не может отказаться от компиляции программы, которая использует asm в качестве идентификатора.

При явном выборе стандарта с помощью -std=c99 также будет удалено ключевое слово asm.Однако вы можете продолжать использовать __asm__, поскольку все имена, начинающиеся с двух подчеркиваний, всегда зарезервированы реализацией для любого использования.


Тем не менее, оно по-прежнему очень плохой стиль, поскольку C99 , ревизии C11 и C17 делают упоминают его как общее расширение .

...