Julia: LLT_ALIGN makes Microsoft VC++ unhappy

Created on 16 Dec 2015  Â·  12Comments  Â·  Source: JuliaLang/julia

this macro

#define LLT_ALIGN(x, sz) (((x) + (sz-1)) & (-sz))

in support/dtypes.h causes Visual C++ to complain with the following warning

julia.h(750) warning C4146: unary minus operator applied to unsigned type, result still unsigned

The macro may likely be right but it unnerves the compiler and because it's in julia.h, it's all over the place littering the output with this warning -- which can be suppressed. It would be nice to have it not do that by default is there's another way to construct the effect.

[pao: insert pinned SHA link to dtypes.h]

build windows

Most helpful comment

@StefanKarpinski However it is required to include when using this feature: Embedding Julia

All 12 comments

I don't see this. What version of MSVC are you using? Are there some more levels of "included from" backtrace?

(also good to hit y so links to lines of code get permalinked with a commit sha)

This is VC++ from Visual Studio Community 2015. Oooh, explain the link sha idea. I'll do that in future.

I I was hoping it was context as well, but no, this is a macro that is used in julia.h and various other src when compiling libjulia, but not intended for direct use externally.

bizarro% find . -type f -exec grep LLT_ALIGN {} /dev/null \;
./alloc.c:        *len = LLT_ALIGN((*len), alignment);
./alloc.c:        size_t nb = l*LLT_ALIGN(jl_datatype_size(elty), alignment);
./alloc.c:    *len = LLT_ALIGN(*len, bt->alignment);
./alloc.c:            size_t alsz = LLT_ALIGN(sz, al);
./alloc.c:    st->size = LLT_ALIGN(sz, alignm);
./APInt-C.cpp:        /* use LLT_ALIGN to round the memory area up to the nearest integerPart-sized chunk */ \
./array.c:#define JL_ARRAY_ALIGN(jl_value, nbytes) LLT_ALIGN(jl_value, nbytes)
./codegen.cpp:    size_t tls_states_size = LLT_ALIGN(sizeof(jl_tls_states_t),
./flisp/flisp.c:    n = LLT_ALIGN(n, 2);   // only allocate multiples of 2 words
./gc.c:    size_t allocsz = LLT_ALIGN(sz + offs, 16);
./gc.c:    memset(page_age(pg), 0, LLT_ALIGN(GC_PAGE_SZ / p->osize, 8));
./gc.c:    pg->ages = (uint8_t*)malloc(LLT_ALIGN(GC_PAGE_SZ / p->osize, 8));
./gc.c:        return 16 - 16376 / 4 / LLT_ALIGN(sz, 16 * 4) + 16 + N;
./gc.c:        return 16 - 16376 / 2 / LLT_ALIGN(sz, 16 * 2) + 24 + N;
./gc.c:    return     16 - 16376 / 1 / LLT_ALIGN(sz, 16 * 1) + 32 + N;
./gc.c:        size_t allocsz = LLT_ALIGN(sz + sizeof(bigval_t), 16);
./gc.c:    const int sz = LLT_ALIGN(sizeof_jl_taggedvalue_t + sizeof(void*), 16);
./gc.c:    const int sz = LLT_ALIGN(sizeof_jl_taggedvalue_t + sizeof(void*) * 2, 16);
./gc.c:    const int sz = LLT_ALIGN(sizeof_jl_taggedvalue_t + sizeof(void*) * 3, 16);
./gc.c:    size_t allocsz = LLT_ALIGN(sz, 16);
./gc.c:    size_t allocsz = LLT_ALIGN(sz, 16);
./intrinsics.cpp:                    LLT_ALIGN(size, ((jl_datatype_t*)ety)->alignment)));
./intrinsics.cpp:                    LLT_ALIGN(size, ((jl_datatype_t*)ety)->alignment)));
./julia.h:    return (char*)s + LLT_ALIGN(sizeof(jl_sym_t), sizeof(void*));
./runtime_intrinsics.c:        size_t nb = LLT_ALIGN(jl_datatype_size(ety), ((jl_datatype_t*)ety)->alignment);
./runtime_intrinsics.c:        size_t nb = LLT_ALIGN(jl_datatype_size(ety), ((jl_datatype_t*)ety)->alignment);
./support/dtypes.h:#define LLT_ALIGN(x, sz) (((x) + (sz-1)) & (-sz))
./task.c:    ssize = LLT_ALIGN(ssize, pagesz);
./task.c:    stk = (char*)LLT_ALIGN((uptrint_t)stk, pagesz);
./task.c:    char *stk = (char*)LLT_ALIGN((uptrint_t)t->stkbuf, pagesz);

in julia.h for context

// inline version with strong type check to detect typos in a `->name` chain
STATIC_INLINE char *jl_symbol_name_(jl_sym_t *s)
{
    return (char*)s + LLT_ALIGN(sizeof(jl_sym_t), sizeof(void*)); 
}

Oh right, I don't have a copy of that version of visual studio installed locally. Here it is running on AppVeyor though, not seeing this warning https://ci.appveyor.com/project/tkelman/julia/build/1.0.687

I get one in c:/projects/julia/src/gc.c(581): warning C4312: 'type cast': conversion from 'unsigned int' to 'void *' of greater size and a bunch about unrecognized flags. How are you building this? You might be missing some of the -D flags that the makefiles are using.

Then it fails to link because I don't have a built copy of LLVM using the right version of visual studio.

we can replace that part of the expression with ~(sz-1) to avoid the warning

I got a way to bypass this error by convert size_t into int :
return (char*)s + LLT_ALIGN(int(sizeof(jl_sym_t)), int(sizeof(void*)));

The problem still occurs in Visual Studio 2019. But it is no longer a warning but an error instead.

Julia no longer attempts to support compiling with MSVC, so I think this can be closed.

@StefanKarpinski However it is required to include when using this feature: Embedding Julia

Can you confirm that replacing -sz with ~(sz-1) works and fixes the problem? If so, we can certainly merge that change.

@JeffBezanson My test in Visual Studio 2017 and 2019 shows that replacing -sz with ~(sz-1) eliminates the error.

Thanks --- could you make a PR for that?

Was this page helpful?
0 / 5 - 0 ratings