欧美vvv,亚洲第一成人在线,亚洲成人欧美日韩在线观看,日本猛少妇猛色XXXXX猛叫

新聞資訊

    本文標題里的觀點很“刺激”,它來自國外一位 Swift 和 Rust 專家 Aria Beingessner,他近日撰寫了一篇文章《C 不再是一種編程語言》,在技術社區引起了熱議。


    Beingessner 和他的朋友 Phantomderp 發現彼此在 C 語言的某個方面都有著高度一致的意見——對 C ABI 感到憤怒,并試圖修復它們。盡管他們各自憤怒的原因不盡相同,但本文作者想要表達的是:“C 被提升到了一個具備聲望和權威的角色,它的統治是如此地絕對和永恒,以至于它完全扭曲了我們之間的對話方式。”“Rust 和 Swift 不能簡單地‘說’自己的母語或舒適的語言——它們必須怪異地模擬 C 的皮膚,并把自己包裹其中,使肉體以同樣的方式起伏。”


    比喻雖尖銳,依據卻不無道理。幾乎任何程序要做任何有用或有趣的事情,它都必須在操作系統上運行。這意味著它必須與那個操作系統交互——而很多操作系統都是用 C 編寫的。因此,該語言必須與 C 代碼交互,這意味著它必須調用 C API。這是通過外部功能接口(FFI)完成的。換句話說,即使你從未用 C 編寫任何代碼,你也必須處理 C 變量、匹配 C 數據結構和布局、通過名稱和符號鏈接到 C 函數。這不僅適用于任何語言與操作系統的交互,也適用于從一種語言調用另一種語言。


    雖然很多人都表示自己喜歡 C,但對文章的內容也是表達了認可和贊同。


    更精確地說,這篇文章的核心并不是“C 不再是編程語言”,而是“C 不僅僅是一種編程語言”。InfoQ 對原文進行了翻譯,以饗讀者。以下內容節選自原文:


    C 是編程通用語言,我們都必須學 C,因此 C 不再只是一種編程語言,它成了每一種通用編程語言都需要遵守的協議。


    本文僅探討“C 由實現定義導致的難以捉摸的混亂”,這個讓所有人都不得不使用的協議已經變成了一個更大的噩夢。

    外部函數接口

    首先,讓我們從技術的角度看看。你完成了新語言 Bappyscript 的設計,它對 Bappy Paws/Hooves/Fins 提供了一流的支持。這是一門神奇的語言,它將徹底改變人們的編程方式!


    但現在,你需要用它做一些有用的事情,比如,接受用戶的輸入,或者輸出結果,或者任何可見的東西。如果你希望用你的語言編寫的程序成為優秀的公民,可以在主要的操作系統上很好地運行,那么你就需要與操作系統接口進行交互。我聽說,Linux 上的任何東西都“只是一個文件”,所以讓我們在 Linux 上打開一個文件。


    OPEN(2)
    
    
    NAME
           open, openat, creat - open and possibly create a file
    
    
    SYNOPSIS
    
    
           #include <fcntl.h>
    
    
           int open(const char *pathname, int flags);
           int open(const char *pathname, int flags, mode_t mode);
    
    
           int creat(const char *pathname, mode_t mode);
    
    
           int openat(int dirfd, const char *pathname, int flags);
           int openat(int dirfd, const char *pathname, int flags, mode_t mode);
    
    
           /* Documented separately, in openat2(2): */
           int openat2(int dirfd, const char *pathname,
                       const struct open_how *how, size_t size);
    
    
       Feature Test Macro Requirements for glibc (see
       feature_test_macros(7)):
    
    
           openat():
               Since glibc 2.10:
                   _POSIX_C_SOURCE >=200809L
               Before glibc 2.10:
                   _ATFILE_SOURCE
    
    

    復制代碼


    對不起,什么?這是 Bappyscript,不是 C。那 Linux 的 Bappyscript 接口在哪里?你說 Linux 沒有 Bappyscript 接口是什么意思!?好吧,這是一種全新的語言,但你會添加一個,對吧?這時候你會想,我們好像必須使用他們給的東西。


    我們將需要某種接口,使我們的語言能夠調用外部函數。外部函數接口,是的,FFI......


    然后你發現,什么,Rust,你也有 C 的 FFI?Swift 你也有嗎?甚至連 Python 也有?!



    為了與主要的操作系統對話,每種語言都必須學會說 C 語言。然后,當它們需要相互對話時,也就都說起了 C 語言。


    現在,C 語言成了編程通用語言。它不再僅僅是一種編程語言,還成了一種協議。

    與 C 交互涉及哪些方面?

    很明顯,幾乎每種語言都必須學會說 C 語言。那么,“說 C 語言”是什么意思?這是說要以 C 語言頭文件的方式描述接口的類型和函數,并以某種方式做一些事情:


    • 匹配這些類型的布局;
    • 用鏈接器做一些事情,將函數的符號解析為指針;
    • 用適當的 ABI 來調用這些函數(比如把參數放在正確的寄存器中)。然而這里有兩個問題:
    • 你不能真的編寫一個 C 解析器;
    • C 并沒有一個 ABI,甚至是定義好的類型布局。

    你不能真的解析一個 C 頭文件

    真的,解析C語言基本上是不可能的。


    “但是,等等!有很多工具可以讀取 C 語言的頭文件,比如rust-bindgen!”


    但還是不行:


    bindgen 使用 libclang 來解析 C 和 C++頭文件。要修改 bindgen 搜索 libclang 的方式,請參閱 clang-sys 文檔。關于 bindgen 如何使用 libclang 的更多細節,請參閱 bindgen 用戶指南。任何花了大量時間嘗試從語法上分析 C(++)頭文件的人,很快就會說“啊,去他的”,并轉而用一個 C(++)編譯器來做這件事。請記住,僅僅從語法上分析 C 頭文件是沒有意義的:你還需要解析 #includes、typedefs 和 macros 的。因此,現在你需要實現平臺所有的頭文件解析邏輯,并以某種方式找到與你所關注的環境相對應的 DEFINED 內容。


    就拿 Swift 這個極端的例子來說吧。在 C 語言互操作和資源方面,它基本上擁有一切優勢。


    該語言是由蘋果公司開發的,它有效地取代了 Objective-C,成為在蘋果平臺上定義和使用系統 API 的主語言。我認為,在這個過程中,它在ABI穩定性和設計方面比其他任何語言都更進一步。


    它也是我見過的對 FFI 支持最好的語言之一。它可以本地導入(Objective-)C(++)頭文件,并生成一個漂亮的原生 Swift 接口,相關類型會自動“橋接”到 Swift 中對等的類型(通常是透明的,因為這些類型的 ABI 相同)。


    Swift 的開發者同時也是蘋果公司 Clang 和 LLVM 項目的構建者和維護人。他們都是 C 語言及其衍生物方面的世界級專家。Doug Gregor 就是其中之一,以下是他對 C FFI 的看法:



    看吧,即便是 Swift 也不愿意做這種事。(另外可以參見Jordan Rose和John McCall在llvm上的PPT去了解“Swift為何采用這種方式”)。


    那么,如果你無論如何也不想使用 C 編譯器在編譯時分析并解析頭文件,那么你要怎么做?你就要“手工翻譯”了!int64_t?還是說寫i64. long?......

    C 實際上并沒有 ABI

    好吧,這沒什么可大驚小怪的:出于“可移植性”考慮,C 語言中的整數類型被設計成大小不固定的。我們可以把賭注押在有點怪異的CHAR_BIT上,但我們還是無法知道long的大小和對齊方式。


    ”但是等等!每個平臺都有標準化的調用約定和 ABI!“


    的確是有,而且它們通常定義了 C 語言中關鍵原語的布局!(而且,其中一些不僅僅定義了 C 類型的調用約定,參見 AMD64 SysV。)


    但這里有一個棘手的問題:其架構中并沒有定義 ABI。操作系統也沒有。我們必須針對特定的目標三元組(target triple)做工作,比如“x86_64-pc-windows-gnu”(不要與“x86_64-pc-windows-msvc”弄混了)。


    好吧,會有多少個這樣的目標三元組呢?


    > rustc --print target-list
    
    
    aarch64-apple-darwin
    aarch64-apple-ios
    aarch64-apple-ios-macabi
    aarch64-apple-ios-sim
    aarch64-apple-tvos
    ...

    復制代碼


    還有:


    ...
    armv7-unknown-linux-musleabi
    armv7-unknown-linux-musleabihf
    armv7-unknown-linux-uclibceabihf
    ...

    復制代碼


    還有:


    ...
    x86_64-uwp-windows-gnu
    x86_64-uwp-windows-msvc
    x86_64-wrs-vxworks
    
    
    >_

    復制代碼


    這樣的目標三元組總共有 176 個。我原本打算都列出來,以增強視覺沖擊,但實在是太多了。ABI 實在是太多了。而且,我們還沒有涉及到所有不同的調用約定,比如 stdcall vs fastcall 或者 aapcs vs aapcs-vfp!


    至少,所有這些 ABI 和調用約定之類的東西肯定要以機器可讀的格式提供給大家使用:冗長的 PDF 文件。


    好吧,至少對于特定的目標三原組,主要的 C 語言編譯器在 ABI 上達成了一致!當然,也有一些奇怪的 C 語言編譯器,如 clang 和 gcc-。


    > abi-checker --tests ui128 --pairs clang_calls_gcc gcc_calls_clang
    
    
    ...
    
    
    Test ui128::c::clang_calls_gcc::i128_val_in_0_perturbed_small        passed
    Test ui128::c::clang_calls_gcc::i128_val_in_1_perturbed_small        passed
    Test ui128::c::clang_calls_gcc::i128_val_in_2_perturbed_small        passed
    Test ui128::c::clang_calls_gcc::i128_val_in_3_perturbed_small        passed
    Test ui128::c::clang_calls_gcc::i128_val_in_0_perturbed_big          failed!
    test 57 arg3 field 0 mismatch
    caller: [30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 3A, 3B, 3C, 3D, 3E, 3F]
    callee: [38, 39, 3A, 3B, 3C, 3D, 3E, 3F, 40, 41, 42, 43, 44, 45, 46, 47]
    Test ui128::c::clang_calls_gcc::i128_val_in_1_perturbed_big          failed!
    test 58 arg3 field 0 mismatch
    caller: [30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 3A, 3B, 3C, 3D, 3E, 3F]
    callee: [38, 39, 3A, 3B, 3C, 3D, 3E, 3F, 40, 41, 42, 43, 44, 45, 46, 47]
    
    
    ...
    
    
    392 passed, 60 failed, 0 completely failed, 8 skipped
    
    

    復制代碼


    這是我在 x64 Ubuntu 20.04 上運行FFI abi-checker的結果。這是一個相當重要的、表現良好的平臺。這里測試的是一些非常令人厭煩的情況,即一些整型參數在兩個由 clang 和 gcc 編譯的靜態庫之間按值傳遞……而且失敗了!甚至是 x64 linux 上的__int128 ABI,clang 和 gcc 也未能達成一致。該類型是一個 gcc 擴展,但 AMD64 SysV ABI 在一個不錯的 PDF 文件里做了明確定義和說明。


    我寫這個東西是為了檢查rustc中的錯誤,我并沒有指望發現,這兩個主要的 C 編譯器在最重要同時人們也最熟悉的 ABI 上存在不一致!


    ABI 就是謊言。

    試著把 C 馴化

    因此,對 C 語言頭文件做語義解析是一個可怕的噩夢,只能由那個平臺的 C 編譯器來完成,即使你讓 C 編譯器告訴你類型以及如何理解注釋,但實際上,你仍然無法知道所有東西的大小/對齊方式/調用約定。


    如何與那堆東西進行互操作呢?


    你的第一個選項是完全投降,將你的語言與 C 語言進行靈魂綁定,可以采用以下任何一種方式:


    • 用 C(++)編寫編譯器/運行時,所以它無論如何都能說 C 語言。
    • 讓你的“codegen”直接生成 C(++),這樣用戶就需要一個 C 編譯器。
    • 基于一個成熟的主流 C 編譯器(gcc 或 clang)構建自己的編譯器。但也僅限于此,因為除非你的語言真的暴露了unsigned long long,否則你就會繼承 C 的可移植性混亂。


    于是,我們來到了第二個選項:撒謊、欺騙和偷竊。


    如果這一切是一場躲不開的災難,那么還不如開始在自己的語言中手工翻譯類型和接口定義。這基本上就是我們在 Rust 中每天都在做的事情。是的,人們使用 rust-bindgen 之類的工具來自動化這個過程,但很多時候,還是需要檢查或手工調整那些定義,生命短暫,實在無法讓經過某人奇怪定制的 C 構建系統可移植。


    嘿,Rust,在x64 linux上intmax_t是什么?


    pub type intmax_t=i64;

    復制代碼


    酷!故事結束了!嘿,Nim,在x64 linux上long long是什么?


    clonglong {.importc: "long long", nodecl.}=int64

    復制代碼


    酷!故事結束了!很多代碼已經從各個環節中剔除了 C,并且已經開始對核心類型的定義進行硬編碼。畢竟,它們顯然只是平臺 ABI 的一部分!它們要做什么?改變intmax_t的大小嗎!?這顯然是一個破壞 ABI 的修改。


    哦,對了,phantomderp正在研究的那個東西又是什么?


    我們談下為什么不能修改intmax_t,因為如果我們從long long(64 位整數)改為__int128_t(128 位整數),某些二進制文件就會無所適從,使用錯誤的調用約定/返回約定。但是,有沒有一種方法——如果代碼選用了——我們可以在新的應用程序中升級函數調用,而讓老的應用程序保持原樣?讓我們編寫一些代碼,測試一下透明別名可以為 ABI 帶來什么幫助。是的,他們的文章真的寫得很好,解決了一些非常重要的實際問題,但是......編程語言如何處理這種變化?如何指定與哪個版本的intmax_t互操作?如果有一些 C 語言頭文件涉及到了intmax_t,它使用哪個定義?


    我們在討論 ABI 不同的平臺時使用的主要機制是目標三元組。你知道什么是目標三元組嗎? x86_64-unknown-linux-gnu。你知道都包括什么嗎?基本上涵蓋了過去 20 年里所有主要的桌面/服務器 Linux 發行版。表面上,你可以針對某個目標進行編譯,并得到一個在所有這些平臺上都能“正常工作”的二進制文件。但是,情況可能并非如此,比如有些程序在編譯時會默認intmax_tint64_t大。


    任何試圖做出這種改變的平臺是不是都會成為一個新的目標三元組? x86_64-unknown-linux-gnu2?如果任何針對x86_64-unknown-linux-gnu編譯的東西都可以在上面運行,這還不夠嗎?

    修改簽名而又不破壞 ABI

    ”那又怎樣,難道 C 語言就永遠不會再改進了嗎?“


    說不是也是,因為它糟糕的設計。


    老實說,進行 ABI 兼容的修改可謂是一種藝術形式。這項工作的一部分是準備。如果你準備好了,做不破壞 ABI 的修改就會簡單很多。


    正如 phantomderp 的文章所指出的那樣,像 glibc(gx86_64-unknown-linux-gnu中的gnu)早就意識到了這一點,并使用符號版本化這樣的機制來更新簽名和 API,同時為任何針對舊版本的編譯保留舊版本。


    因此,如果有個方法int32_t my_rad_symbol(int32_t),你告訴編譯器將其導出為my_rad_symbol_v1,那么任何針對你所提供的頭文件進行編譯的人,都會在代碼中寫上my_rad_symbol,但會鏈接到my_rad_symbol_v1


    然后,當你確定實際應該使用int64_t時,可以把int64_t my_rad_symbol(int64_t)當作my_rad_symbol_v2,但仍然保留舊的定義my_rad_symbol_v1。 任何人在針對你的頭文件進行編譯時,如果是針對新版本就使用符號v2,而針對舊版本則繼續使用v1


    但仍然有一個兼容性問題:任何針對新的頭文件所做的編譯都不能與舊版本的庫進行鏈接!庫的 v1 版本根本沒有 v2 符號。所以,如果你想要熱門的新功能,就需要接受與舊有系統不兼容的事實。


    不過,這并不是什么大問題,只是會讓平臺供應商感到難過,因為沒有人能夠立即使用他們花了這么多時間做出來的東西。你推出了一個閃亮的新特性,卻要放在手里等數年的時間,等到大家認為它變得足夠普及/成熟,愿意依賴它并打破對舊平臺的支持(或者愿意為它實現動態檢查和回退)。


    如果你想讓人們立即升級,那么就是向前兼容的問題了。這就需要讓舊版本能夠適應它們完全沒有概念的新特性。

    修改類型而不破壞 ABI

    好了,除了修改函數的簽名,我們還可以修改什么?我們可以修改類型布局嗎?


    可以!但也不可以!這取決于你暴露類型的方式。


    C 語言真正奇妙的其中一個功能是,它讓你可以區分布局已知的類型和布局未知的類型。如果你只在 C 語言的頭文件中前向聲明一個類型,那么任何與該類型交互的用戶代碼都無法知道該類型的布局,而必須一直通過指針不透明地對它做處理。


    所以你可以開發一個像MyRadType* make_val()use_val(MyRadType*)這樣的 API,然后利用同樣的符號版本化技巧來暴露make_val_v1use_val_v1,任何時候你想修改這個布局,都要在與該類型交互的所有東西上修改版本。同樣地,你得保留MyRadTypeV1MyRadTypeV2和一些類型定義,以確保人們使用“正確”的類型。


    很好,我們可以改變不同版本之間的類型布局!對嗎?嗯,大多數時候是這樣。


    如果有多個東西基于你的庫構建,它們在類型不透明的情況下相互調用,就會出現糟糕的情況:


    • lib1:開發一個 API,使用類型MyRadType*調用use_val
    • lib2:調用make_val ,并將結果傳給 lib1。如果 lib1 和 lib2 是基于庫的不同版本進行編譯的,那么make_val_v1就會被傳遞給use_val_v2!這時,你有兩個選擇來處理這個問題:


    1. 禁止這樣做,警告那些這樣做的人,令人傷心。
    2. 以一種向前兼容的方式設計MyRadType,這樣混用就沒問題了。實現向前兼容常用的技巧有:


    • 保留未使用的字段供未來版本使用。
    • MyRadType 的所有版本都有一個共同的前綴,讓你可以“檢查”所使用的版本。
    • 有大小自適應的字段,這樣舊版本可以“跳過”新增部分。

    案例分析:MINIDUMP_HANDLE_DATA

    微軟確實是向前兼容的大師,他們甚至讓他們真正關心的東西在不同的架構之間保持布局兼容。我最近遇到的一個例子是Minidumpapiset.h中的MINIDUMP_HANDLE_DATA_STREAM。


    這個 API 描述了一個版本化的值列表。該列表以這種類型開始:


    typedef struct _MINIDUMP_HANDLE_DATA_STREAM {
        ULONG32 SizeOfHeader;
        ULONG32 SizeOfDescriptor;
        ULONG32 NumberOfDescriptors;
        ULONG32 Reserved;
    } MINIDUMP_HANDLE_DATA_STREAM, *PMINIDUMP_HANDLE_DATA_STREAM;
    
    

    復制代碼


    其中:


    • SizeOfHeader是 MINIDUMP_HANDLE_DATA_STREAM 本身的大小。如果需要在末尾添加更多的字段,那也沒關系,因為舊版本可以使用這個值來檢測頭的“版本”,并跳過任何它們不識別的字段。
    • SizeOfDescriptor是數組中每個元素的大小。這也是為了讓你知道元素是什么“版本”,你可以跳過不知道的字段。
    • NumberOfDescriptors是數組長度。
    • Reserved是一個保留字段(Minidumpapiset.h非常嚴謹,從不使用任何填充字節,因為填充字節的值未定,而且是一種序列化的二進制文件格式。我希望他們添加這個字段是為了使結構的大小是 8 的倍數,這樣就不會有數組元素是否需要在頭之后填充的問題了。哇,這才是認真對待兼容性!)事實上,微軟使用這種版本化方案是有原因的,他們定義了兩個版本的數組元素:


    typedef struct _MINIDUMP_HANDLE_DESCRIPTOR {
        ULONG64 Handle;
        RVA TypeNameRva;
        RVA ObjectNameRva;
        ULONG32 Attributes;
        ULONG32 GrantedAccess;
        ULONG32 HandleCount;
        ULONG32 PointerCount;
    } MINIDUMP_HANDLE_DESCRIPTOR, *PMINIDUMP_HANDLE_DESCRIPTOR;
    
    
    typedef struct _MINIDUMP_HANDLE_DESCRIPTOR_2 {
        ULONG64 Handle;
        RVA TypeNameRva;
        RVA ObjectNameRva;
        ULONG32 Attributes;
        ULONG32 GrantedAccess;
        ULONG32 HandleCount;
        ULONG32 PointerCount;
        RVA ObjectInfoRva;
        ULONG32 Reserved0;
    } MINIDUMP_HANDLE_DESCRIPTOR_2, *PMINIDUMP_HANDLE_DESCRIPTOR_2;
    
    
    // 最新MINIDUMP_HANDLE_DESCRIPTOR定義。
    typedef MINIDUMP_HANDLE_DESCRIPTOR_2 MINIDUMP_HANDLE_DESCRIPTOR_N;
    typedef MINIDUMP_HANDLE_DESCRIPTOR_N *PMINIDUMP_HANDLE_DESCRIPTOR_N;

    復制代碼


    關于這些結構的實際細節,有幾個比較有趣的地方:


    • 對它的修改只是在末尾添加字段;
    • “最后一個”有類型定義;
    • 保留一些 Maybe Padding(RVA 是 ULONG32 類型)。在向前兼容性方面,微軟絕對是一頭堅不可摧的巨獸。他們對填充如此謹慎,甚至在 32 位和 64 位之間采用了相同的布局!(實際上,這非常重要,因為你希望一個架構的小型轉儲文件處理器能夠處理每個架構的小型轉儲文件。)


    好吧,至少它真的很健壯,如果你按照它的規則來,通過引用進行操作,并使用 size 字段。


    但至少可以玩下去。只是在某些時候,你不得不說“你的用法不對”。微軟可能不會這么說,他們只會做一些可怕的事。

    案例分析:jmp_buf

    我對這種情況不是很熟悉,但在研究 glibc 歷史上的破壞性修改時,我在 lwn 上看到了這篇很棒的文章:glibc s390 ABI的破壞性修改。我認為這篇文章比較準確。


    事實證明,glibc 曾經破壞過類型的 ABI,至少在 s390 上是這樣。根據這篇文章的描述,它造成了混亂。


    特別地,他們改變了setjmp/longjmp使用的狀態保存類型(即jmp_buf)的布局。看吧,他們并不是十足的傻瓜。他們知道這是一個破壞 ABI 的修改,所以他們負責任地做了符號版本化。


    但是,jmp_buf并不是一個不透明類型。有些東西內聯地存儲了這個類型的實例,比如 Perl 的運行時。不用說,這個相比之下不是很容易理解的類型已經滲透到許多二進制文件中去了,最終的結論是,Debian 的所有東西都需要重新編譯。


    這篇文章甚至討論了對 libc 進行版本升級以應對這種情況的可能性:


    在像 Debian 這樣的混合 ABI 環境中,SO 名稱的改變(SO name bump)會導致兩個 libc 被加載并競爭相同的符號命名空間,而解析(以及 ABI 選擇)由 ELF 插值和作用域規則決定。這真是一場噩夢。這可能是一個比告訴所有人重新構建并回歸正常軌道更糟糕的解決方案。(這篇文章很不錯,強烈建議您讀一下。)

    真的能修改 intmax_t?

    在我看來,未必。和jmp_buf一樣,它不是一個不透明類型,也就是說,它被大量的隨機結構內聯,被其他大量的語言和編譯器視為一個特定的表示,并且可能存在于大量的公共接口中,而這些接口不在 libc、linux、甚至發行版維護者的控制之下。


    當然,libc 可以適當地使用符號版本化技巧,使其 API 可以適應新的定義,但是,改變一個基本數據類型(像intmax_t)的大小,會在更大的平臺生態系統中引發混亂。


    如果有人能夠證明我是錯的,我會很高興,但據我所知,做出這樣的改變需要一個新的目標三元組,并且不允許任何為舊 ABI 構建的二進制文件/庫在這個新三元組上運行。當然,你可以這樣做,但我并不羨慕任何做了這些工作的發行版。


    即使如此,還有 x64 int 的問題:它是非常基本的類型,而且長期以來大小從沒變過,無數的應用程序可能對它做了無法察覺的假設。這就是為什么 int 在 x64 上是 32 位的,盡管它“應該”是 64 位的:int 長期以來都是 32 位,以至于將軟件升級到新的大小完全無望,盡管它是一個全新的架構和目標三元組。


    我也希望我的觀點是錯的。如果 C 語言只是一種獨立的編程語言,那我們就可以毫無顧慮地往前沖。但它實際上不是了,它是一個協議,還是一個糟糕的協議,而我們還必須要用它。


    很遺憾,C,你征服了世界,但或許不再擁有往昔的美好。


    原文鏈接:https://gankra.github.io/blah/c-isnt-a-language

    社會變革,思想先行。1978年,中國即將迎來舉世矚目的改革開放。在十一屆三中全會召開之前,文化屆已悄然發生變化,預示著這一政策的到來。

    1978年1月上海譯文出版社成立。一些文革前就已出版的外國經典名著又被重新包裝出版上市,比如,上海譯文的《斯巴達克斯》、《紅與黑》等。飽嘗十年書荒的人們擁進各地新華書店,排隊憑票購買圖書,萬人空巷。今天想來那場景仍十分令人動容。

    人們在新華書店排隊買書

    1978年8月上海譯文旗下的雙月刊《外國文藝》創刊,意為向中國讀者譯介外國現當代文藝作品。

    復旦大學中文系教授陳思和在一篇題為“想起了《外國文藝》創刊號”的文章中寫道:

    這個雜志創刊于1978年的下半年。當時思想文化界的背景是:中國文化藝術界剛剛從一場噩夢中驚醒過來,戰戰兢兢地向異域文化打開了門窗。

    The magazine was founded in late 1978, when China's literary and art circles had just woken up from the 'cultural revolution' and were cautiously opening the doors and windows to foreign culture and art.

    那年5月1日,全國新華書店出售經過精心挑選的新版古典文學名著《悲慘世界》《安娜·卡列尼娜》《高老頭》等,造成了萬人空巷搶購的局面;而共時性的西方現代主義文學在中國卻沒有獲得這樣的光榮,它暫時還是一個被人因無知而需要小心回避的文化黑洞。

    On May 1, 1978, people crowded into Xinhua Bookstores in cities across China to buy carefully chosen literary classics of new editions such as Victor Hugo's Les Miserables, Leo Tolstoy'sAnna Kareninaand Honore de Balzac'sPere Goriot. Modern Western literature, however, was still regarded as a cultural black hole that we needed to treat cautiously, due to ignorance.

    但是對經受了殘酷與絕望不亞于二次大戰的中國知識分子,尤其是年輕的知識分子而言,他們一時還難以從巨大的理想破碎和荒誕人生的打擊下緩過神來,他們急需從世界的普遍經驗中來理解他們自己的處境以及如何感受這種處境。自然,在一陣閱讀狂喜過后,他們很快就不滿足于那些遙遠而美好的古典名著。

    But for Chinese intellectuals who had suffered cruelty and despair as severe as that of the WWII, especially young people, they were yet able to recover from the collapse of their ideals and the blow of the absurd fate, so they needed to borrow universal experience from other countries to understand their situations and how they should feel about these situations. After reading those classics with wild excitement, young people soon were not able to be satisfied with those ancient classics of beauty and goodness.

    而在《外國文藝》創刊號中,年輕的陳思和讀到了川端康成的短篇小說《伊豆的歌女》和《水月》、意大利詩人蒙塔萊的抒情詩、薩特的《骯臟的手》、約瑟夫·赫勒的《第22條軍規》。

    這些新穎的審美觀為正在改革開放中的中國讀者和作者打開了一扇通往現代社會的大門。加上后來流行的拉美魔幻現實主義、博爾赫斯的《交叉花園的小徑》。這些現代主義、后現代主義小說、詩歌和劇本帶著外國文藝工作者對于世界的思考深深地影響了那一代中國現作家、詩人:莫言、賈平凹、格非等。

    陳思和寫道,這份雜志“是把我融化到這個世界里去,以致使我發現了自己心靈本身就應該是一個新世界:一種屬于現代社會環境里的精神狀態。”

    Reading the bimonthly allowed me to blend into the modern world. I found that my mind should have belonged to a new world: a mental situation in a modern social environment.

    正如他所說:

    在我們還處于蒙昧狀態時我們并不是不會感受,只是我們無以名狀這些感受,也無以對應這些感受,于是我們會感到恐怖。如果一旦有種思想告訴我們這個世界的人都在感受著與我們相同的苦惱和焦慮,或者告訴我們作為一個人本該就是這樣感受著苦惱與焦慮的,那么,我們突然會對自己擁有了嶄新的理解,原來像是打量一個陌生人那樣的眼光會變得溫柔,因為你最終發現了這個陌生人就是你自己。

    這也是閱讀文藝作品之于人的意義吧。

    1979年,剛剛打開國門的中國人渴望了解世界,信息高速公路的修建還要到十幾年以后。于是上海譯文出版社推出了雙月刊《世界之窗》,也是通過翻譯向中國讀者講述世界其他地方正在發生的事情。

    這本雜志很受歡迎,也許很多讀者都讀過。有一期就講到了邁克爾·杰克遜。

    上海譯文出版社、作家出版社、外國文學出版社、漓江出版社等在八十年代向內地譯介了大量的歐美現當代文學:

    《百年孤獨》、《雪國》、《康拉德小說選》、《喧嘩與騷動》、《小城畸人》、《蠅王》、《菲茨杰拉德小說選》、《一個青年藝術家的畫像》、《偽幣制造者》、《細雪》、《斯·茨威格小說選》、《看不見的人》、《西線無戰事》、《喪鐘為誰而鳴》、《憤怒的葡萄》、《曼斯菲爾德短篇小說選》、《鐵皮鼓》、《舊地重游》、《好兵帥克》、《裸者與死者》、《鋼鐵是怎樣煉成的》、《風中蘆葦》、《達洛衛夫人/到燈塔去》、《兒子與情人》、《刀鋒》、《豪門春秋》、《廣漠的世界》、《幼師》、《二神父》、《麥田里的守望者》、《日瓦戈醫生》、《洛麗塔》、《挪威的森林》、《惡之花》、《荊棘鳥》、《霍亂時期的愛情》、《百年孤獨》、《生命中不能承受之輕》、《卡夫卡短篇小說選》、《福克納中短篇小說選》等。

    在上海譯文的“二十世紀文學叢書”中,不僅有英國、美國、法國、德國、西班牙、日本、前蘇聯、意大利等國的文學作品,還有墨西哥、瑞典、阿根廷、冰島、秘魯、捷克、波蘭、厄瓜多爾、埃及等國的作品。

    除了文學作品,各出版社也推出了外國文藝理論叢書。如人民文學的《古代印度文藝理論文選》、《論文學》、《拉奧孔》、《歌德談話錄》、《詩學 詩藝》、《文藝對話集》、《十九世紀英國詩人論詩》,上海譯文的《二十世紀文學評論》、《雨果論文學》、《公園深處》,三聯書店的《二十世紀文學理論》、《美國作家論文學》等。

    1985年,上海譯文推出了“二十世紀西方哲學譯叢”,也就是“黑皮書系列”,陸續出版《人論》、《現象學的觀念》、《單向度的人》、《存在主義是一種人道主義》、《愛欲與文明》等一批影響深遠的哲學書籍。

    譯文40周年展

    八十年代末起,上海譯文又先后推出了《簡愛》、《呼嘯山莊》等作品。1991年,譯文為出版《亂世佳人》的續集《斯嘉麗》購買了版權,這是中國大陸出版社首次取得國外暢銷書的獨家授權。中國政府于1992年才加入世界《保護文學和藝術作品伯爾尼公約》。

    八十年代,更多的出版社成立,包括1986年成立的廣西師范大學出版社,和1988年成立的譯林出版社、中信出版社和南海出版社。

    譯林出版社的前身是70年代末創刊的雜志《譯林》,創辦宗旨是“打開窗口,了解世界”。

    《譯林》創刊號

    三十年來,譯林推出了 “經典譯林”、“譯林傳記”、“牛津通識讀本”、“雙語譯林”、“人文與社會譯叢”“譯林人文精選”、“法政科學叢書”、“西方政治思想譯叢”、“藝術與社會譯叢”、“城市與生態文明系列”等一批代表性品牌書系。

    其中,譯林版《追憶似水年華》、《尤利西斯》、《莎士比亞全集》、《英國工人階級的形成》、《自由論》、《理想國》、《物種起源》、《荊棘鳥》、《查令十字街84號》、《麥田里的守望者》、《殺死一只知更鳥》、《芒果街上的小屋》、《少年Pi的奇幻漂流》、《我的孤獨是一座花園》、《倫敦傳》、《梵高傳》等數百種作品暢銷不衰。

    以經管類圖書聞名的中信出版社新世紀以來引進了很多家喻戶曉的暢銷書:《誰動了我的奶酪》、《史蒂夫·喬布斯傳》、《從0到1》、《人類簡史》、《未來簡史》等。

    2000年,人民文學出版社出版了英國作家JK 羅琳的《哈利·波特與魔法石》。風靡全球的哈利·波特系列也在中國找到了一批忠實的讀者,包括我本人。

    2006年世紀文景出版了《追風箏的人》,暢銷十年,目前印量達到1000萬冊。世紀文景還引進了羅貝托·波拉尼奧的《2666》、托爾金的《魔戒》等高品質圖書。

    新世紀以來,出版社逐漸走向市場化。2006年之后,上海譯文出版社社科室學術類書籍和面向大眾的科普類圖書的比例由原先的8:2調整為2:8。

    社科室主任張吉人于2003年入社。他很喜歡《紐約客》雜志駐中國記者何偉的文章。2006年何偉的《江城》在美國出版,但卻遲遲不肯出售中文版權。

    2010年何偉出版了《尋路中國》,終于愿意出售其中文版權,張吉人第一時間購買到版權。《尋路中國》大受歡迎,譯文又接著出版了《江城》。

    何偉

    到2013年,譯文社科室逐漸形成了“譯文紀實系列”。目前為止這個系列已經出版了近30種書。包括《再會,老北京》、《血疫》、《魚翅與花椒》、《無緣社會》、《女性貧困》、《窮忙》、《老后破產》、《打工女孩》、《最后的熊貓》、《貨幣戰爭》等。

    非虛構寫作也逐漸在中國流行起來。

    Country DrivingandRiver Town, also by Hessler, have each sold more than 300,000 copies in China.Shark Fins and Sichuan Pepper, a book on Chinese food by British writer and cook Fuchsia Dunlop, which was published in July, has been reprinted four times.

    何偉的《尋路中國》和《江城》現在在中國的銷量均超出30萬冊。英國作者、廚師扶霞·鄧洛普的《魚翅與花椒》七月上市,也已加印了四次。

    "Writers like Hessler, Dunlop and Michael Meyer, who wrote The Last Days of Old Beijing, observe Chinese society, people, cities and culture through foreign eyes, providing very different but interesting perspectives for us to understand China in a broader sense," Zhang said.

    “像何偉、鄧洛普和《再會,老北京》的作者梅英東,這些作者,透過外國人的視角觀察中國的社會、人、城市和文化,給我們提供了新鮮有趣的角度,去從廣的視野里理解中國,”張吉人說。

    "I love River Townthe most because it is well written. Its style is unique. Through the descriptions of details in Chinese people's daily lives, you can see the changes that have taken place in China in the past three decades, which I think is also why Chinese people like him," he said.

    “我最喜歡《江城》,因為寫的好、風格獨特。透過中國人日常生活的細致描寫,你可以看到過去三十年來中國發生的變化,我想這也是為什么中國人喜歡他的作品的原因,”他說。

    而像《無緣社會》、《女性貧困》和《老后破產》這樣講老齡化的日本社會的圖書,則可以給我們提供一個參照。現在的日本可能就是20年后中國的樣子。

    上海譯文出版社文學編輯室里活躍著一批年輕的編輯,顧真就是其中的一位。顧真,30歲,2013年入社。除了編輯圖書,他還給《上海書評》寫淘書專欄,業余時間也翻譯書。

    "If you look at the contributors to STPH's Classic Translations Series, many of them are also translators. It's a company tradition. Editors can do things they like-more than just editing books-such as writing or translating," Gu said.

    “上海譯文出版社譯文經典系列的特殊貢獻者中,很多都是譯者。這是譯文社的傳統。編輯可以做自己喜愛的事,不僅是編輯圖書,還可以寫作和翻譯,”顧真說。

    Books that feature well-known writers discussing literature and art are becoming more popular, with Nabokov's Lectures on Literature,Lectures on Russian LiteratureandLectures on Don Quixote, published by the Shanghai Translation Publishing House, selling well.

    近來著名作家聊文藝的圖書很好賣。上海譯文出版的納博科夫的《文學講稿》、《俄羅斯文學講稿》和《堂吉訶德講稿》賣的不錯。

    "Before, we relied on Lolitato sell Nobokov's other works... but only Lolitasold well. But this year, these lectures on literature have sold well on their own without the influence ofLolita," Gu Zhen said.

    “以前我們都是靠《洛麗塔》賣納博科夫的其他作品的,但是只有《洛麗塔》賣的好。但是今年,這些文學講稿靠自己賣的就不錯,”顧真說。

    He has been attempting to tread his own path as an editor, striving to find a balance between his own tastes and those of the public.

    顧真一直在找尋自己作為編輯的道路,努力在自己的喜好和大眾的品味之間尋找平衡。

    "One of the projects that I am working on concerns the five books by Edward St Aubyn that feature Patrick Melrose, which were adapted for a TV series in Britain. Gu said.

    “我手上正在做的一套書是愛德華·圣奧賓講帕特里克·梅爾羅斯的五本書。英國已經出電視劇了,”他說。

    《梅爾羅斯》劇照

    Gu Aibin, editor-in-chief of Yilin Press, said that in the past 30 years, books published by the company have ranged from foreign literature to liberal arts and, more recently, popular science works, clearly mirroring the changing demands of Chinese readers.

    譯林出版社總編輯顧愛彬說,過去三十年來,譯林出版的圖書品類從外國文學拓展到人文社科,再到近年來的科普新知,鮮明地體現了中國讀者閱讀需求的變化。

    "Thirty years ago, readers devoured anything available due to the shortage of books. Now, they choose books very carefully for an enjoyable reading experience, which is the result of the 40 years of reform and opening-up. People's material lives have been greatly improved, so have their spiritual lives."

    “讀者從三十年前解決溫飽似的粗放式閱讀發展到現在精挑細選、講究個人享受體驗的高質量閱讀。這主要是因為四十年的改革開放,人民的物質生活質量得到前所未有的提高,對精神生活和文化生活的期待越來越高。”

    改革開放四十載來,中國社會、經濟、科技、法制、文化的進步都離不開知識和思想的滋養。四十年來,我國的圖書出版業從十年文革結束后的荒蕪之地變成今天的精神糧倉。

    今天,新中國迎來了69歲華誕。在這個特殊的日子,祝祖國繁榮昌盛,人民幸福安康。

    有一位年近五十的老媒體人,每天在朋友圈報告自己當日的鍛煉情況,結尾總說:建設自己,就是建設社會主義新中國。

    在這樣一個瞬息萬變的時代里,能稱作愛國之舉的,不是在網絡上夸夸其談,而是作為理性公民,去努力提高自身文化水平、職業素養、道德標準、健康狀況、文明程度,各司其職,團隊合作,才能讓這個國家長久的強盛。

    一個最簡單的方式就是讀書。

    互動

    你每年大約讀多少本書?哪本是你的最愛呢?對于改革開放40年來的圖書文化界的變化,你又有什么樣的感受?評論區見!

    給雙語君設星標

    最近微信又改版了,小可愛們一定記得把雙語君設為“星標”哦!

    這樣就能第一時間找到我們啦!學習英語不迷路!

    設置“星標”步驟↓↓

    編輯:唐曉敏

網站首頁   |    關于我們   |    公司新聞   |    產品方案   |    用戶案例   |    售后服務   |    合作伙伴   |    人才招聘   |   

友情鏈接: 餐飲加盟

地址:北京市海淀區    電話:010-     郵箱:@126.com

備案號:冀ICP備2024067069號-3 北京科技有限公司版權所有