unittests: Add a test for TV_CSTRING

Not using enum{} because SIZE_MAX exceeds integer and I do not really like how
enum definition is described in C99:

1. Even though all values must fit into the chosen type (6.7.2.2, p 4) the type
   to choose is still implementation-defined.
2. 6.4.4.3 explicitly states that “an identifier declared as an enumeration
   constant has type `int`”. So it looks like “no matter what type was chosen
   for enumeration, constants will be integers”. Yet the following simple
   program:

        #include <stdint.h>
        #include <stdio.h>
        #include <stddef.h>

        enum { X=SIZE_MAX };

        int main(int argc, char **argv)
        {
          printf("x:%zu m:%zu t:%zu v:%zu",
                 sizeof(X), sizeof(SIZE_MAX), sizeof(size_t), (size_t)X);
        }

    yields one of the following using different compilers:

    - clang/gcc/pathcc: `x:8 m:8 t:8 v:18446744073709551615`
    - pcc/tcc: `x:4 m:8 t:8 v:1844674407370955161`

    If I remove the cast of X to size_t then pcc/tcc both yield `x:4 m:8 t:8
    v:4294967295`, other compilers’ output does not change.

    All compilers were called with `$compiler -std=c99 -xc -` (feeding program
    from echo), except for `tcc` which has missing `-std=c99`. `pcc` seems to
    ignore the argument though: it is perfectly fine with `-std=c1000`.
This commit is contained in:
ZyX 2017-04-14 00:12:05 +03:00
parent 276ee1f7fb
commit b54e5c220f
2 changed files with 11 additions and 0 deletions

View File

@ -17,6 +17,7 @@
#include "nvim/pos.h" // for linenr_T
#include "nvim/gettext.h"
#include "nvim/message.h"
#include "nvim/macros.h"
/// Type used for VimL VAR_NUMBER values
typedef int varnumber_T;
@ -434,6 +435,12 @@ static inline bool tv_is_func(const typval_T tv)
/// Used for size_t length arguments to avoid calling strlen() unless needed.
#define TV_CSTRING (SIZE_MAX - 1)
#ifdef UNIT_TESTING
// Do not use enum constants, see commit message.
EXTERN const size_t kTVCstring INIT(= TV_CSTRING);
EXTERN const size_t kTVTranslate INIT(= TV_TRANSLATE);
#endif
#ifdef INCLUDE_GENERATED_DECLARATIONS
# include "eval/typval.h.generated.h"
#endif

View File

@ -2450,6 +2450,10 @@ describe('typval.c', function()
'E741: Value is locked: Unknown'))
eq(true, tv_check_lock(lib.VAR_FIXED, nil, 0,
'E742: Cannot change value of Unknown'))
eq(true, tv_check_lock(lib.VAR_LOCKED, nil, lib.kTVCstring,
'E741: Value is locked: Unknown'))
eq(true, tv_check_lock(lib.VAR_FIXED, 'test', lib.kTVCstring,
'E742: Cannot change value of test'))
end)
end)
describe('equal()', function()