0

I am inspired by this answer.

The one way I thought of was a combination of static_assert (C11-onwards) and assert.

Basically, an ascii.h file with a bunch of

static_assert(' ' == 32);
static_assert('!' == 33);
// ...

statements and then a function

static void assert_runtime_ascii(void) {
    assert(' ' == 32);
    assert('!' == 33);
    // ...
}

to be executed in main.

This is way too verbose (200+ lines) making this impractical, so I just comment this

// NOTE: this program expects ASCII both at run-time and compile-time.

and be done.

Is there a better way?

I could not find a #define like __STDC_IEC_559__ for ASCII in the standard.

Is there a better way?

John Kugelman
  • 349,597
  • 67
  • 533
  • 578
MarkWeston
  • 740
  • 4
  • 15
  • In what way is it impractical? Just include the file. – klutt Feb 08 '20 at 00:10
  • 1
    Practically speaking, you don't need 200 lines. If `' ' == 32`, `'!' == 33`, `'0' == 48`, `'A' == 65`, and `'a' == 97'`, you can be 99+% sure you have an ASCII-compatible character set (possibly Latin-1 or some flavor of Unicode). Check a few more punctuation characters if you're concerned about old 7-bit character sets that shove regional characters into the ASCII range. But keep in mind that if your code is compiled on a non-ASCII system, it will have been translated from the ASCII encoding in which you typed it. – Keith Thompson Feb 08 '20 at 00:20
  • Possibly use a hash-value of a few `const char` strings? – Adrian Mole Feb 08 '20 at 00:21
  • What's the point in asserting ASCII encoding? When you build your code, you **know** the encoding of the OS on that particular architecture, so you don't have to check anything, when you can pass a `-DNOT_ASCII=1` option to the compiler. – Pablo Feb 08 '20 at 01:09
  • "too verbose (200+ lines)" is unclear as ASCII only defines 128 characters. – chux - Reinstate Monica Feb 08 '20 at 01:19
  • `assert(' ' == 32);` is not really run-time check as the code may be optimized at compile time. – chux - Reinstate Monica Feb 08 '20 at 01:29
  • You could make the code more compact with something like assert(0 == strcmp( " !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~", "\040\041\042\043\044\045\046\047\050\051\052\053\054\055\056\057\060\061\062\063\064\065\066\067\070\071\072\073\074\075\076\077\100\101\102\103\104\105\106\107\110\111\112\113\114\115\116\117\120\121\122\123\124\125\126\127\130\131\132\133\134\135\136\137\140\141\142\143\144\145\146\147\150\151\152\153\154\155\156\157\160\161\162\163\164\165\166\167\170\171\172\173\174\175\176" )); – Gene Feb 08 '20 at 01:48
  • @Pablo "When you build your code, you know the encoding of the OS on that particular architecture" --> Not always as code is ported and shared. A fair amount of code compiling involves automation - there is no programmer to "know" – chux - Reinstate Monica Feb 08 '20 at 01:54
  • @Gene Needs a little work with `...[\]...` --> `...[\\]...` and perhaps also test `\t\v\n\f`. Looks like a foundation for more than just a comment. – chux - Reinstate Monica Feb 08 '20 at 02:02

1 Answers1

0

best way to guarantee ASCII both at compile-time and run-time?

It sounds like OP wants to know how to detect the execution character set encoding and user I/O encoding.

At compile time or run-time, to detect ASCII, use a series of _Static_asserts or asserts (example code) for most of the 128 ASCII characters, the ones that are part of the C language execution character set. C11 §5.2.1 3

A to Z
a to z
0 to 9
! " # % & ’ ( ) * + , - . / : ; < = > ? [ \ ] ^ _ { | } ~
space character, 
  and control characters representing horizontal tab, vertical tab, and form feed.
some way of indicating the end of each line of text

Note that characters like "$, @,`" are not part of the execution character set so "if there is no corresponding member, it is converted to an implementation-defined member other than the null (wide) character" applies.


To detect encoding of user input/output, I do not see a solution short of asking the user to enter a reference text and code checking it.

chux - Reinstate Monica
  • 143,097
  • 13
  • 135
  • 256