Skip to content

sync.stdatomic breaks under -cc tcc #28026

Description

@nepinhum

Describe the bug

sync.stdatomic breaks under -cc tcc

Redundant #include <stdatomic.h> in 1.declarations.c.v reintroduces the exact problem its own tcc compat header guards against

vlib/sync/stdatomic/1.declarations.c.v inserts a bundled, tcc safe header (thirdparty/stdatomic/nix/atomic.h) that correctly guards against needing the real system <stdatomic.h> under tcc:

#ifndef __TINYC__
#include <stdatomic.h>
#endif
But immediately after inserting that header, 1.declarations.c.v itself does a second, unguarded real include for tcc builds (lines ~21-22):
$if tinyc {
    #include <stdatomic.h>
    $if linux {
        #insert "@VEXEROOT/vlib/sync/stdatomic/tcc_compat_linux_fence.h"
    }
}

This second include is redundant, everything needed was already declared by the compat header above and it reintroduces exactly the failure the guard was written to prevent. tcc can't reliably compile GCC's real <stdatomic.h>

tcc -E -dM - < /dev/null predefines zero _ATOMIC* macros (GCC's header needs __ATOMIC_RELAXED, __ATOMIC_SEQ_CST, etc.)

Reproduction Steps

test.v:

module main

import sync.stdatomic

fn main() {
     mut a := stdatomic.new_atomic(i64(0))
     a.store(1)
     println(a.load())
}

v -cc tcc -no-retry-compilation run test.v:
builder error: 'stdatomic.h' not found

Expected Behavior

Compiles and runs under tcc, since the bundled compat header already declares everything sync.stdatomic needs without touching the real system header.

Current Behavior

builder error: 'stdatomic.h' not found
tcc can't locate GCC's private header directory. On a system where tcc can locate that header, the failure instead becomes error: '__ATOMIC_RELAXED' undeclared

Possible Solution

Remove the redundant #include <stdatomic.h> (and the tcc_compat_linux_fence.h insert that depends on it) from the $if tinyc block in 1.declarations.c.v
The preceding #insert "@VEXEROOT/thirdparty/stdatomic/nix/atomic.h" already declares everything for tcc. If tcc_compat_linux_fence.h's fence symbol direction fix is still needed without that real include present, it should be rederived against the bundled compat header instead of against the real system header.

Additional Information/Context

Found while investigating why a project using sync.stdatomic for lock free counters always silently falls back from tcc to cc under v run, with no indication why.

V version

V 0.5.2 76f77e3.5fc71b2

Environment details (OS name and version, etc.)

V full version V 0.5.2 76f77e3.5fc71b2
OS linux, "EndeavourOS Linux"
Processor 8 cpus, 64bit, little endian, Intel(R) Core(TM) i5-10300H CPU @ 2.50GHz
Memory 0.6GB/7.62GB
V executable /home/scher/v/v
V last modified time 2026-08-04 11:52:06
V home dir OK, value: /home/scher/v
VMODULES OK, value: /home/scher/.vmodules
VTMP OK, value: /tmp/v_1000
Current working dir OK, value: /home/scher/projects/vlang/netherrack/vedrock
Git version git version 2.55.0
V git status 0.5.2-211-g5fc71b2d
.git/config present true
cc version cc (GCC) 16.1.1 20260728
gcc version gcc (GCC) 16.1.1 20260728
clang version clang version 22.1.8
tcc version tcc version 0.9.27 (x86_64 Linux)
tcc git status HEAD c29a7c89
emcc version N/A
glibc version ldd (GNU libc) 2.44

Note

You can use the 👍 reaction to increase the issue's priority for developers.

Please note that only the 👍 reaction to the issue itself counts as a vote.
Other reactions and those to comments will not be taken into account.

Metadata

Metadata

Assignees

No one assigned

    Labels

    BugThis tag is applied to issues which reports bugs.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions