Skip to content

libap: `asctime_r' was declared by no header, found by calling it - #713

Merged
staalmannen merged 1 commit into
mainfrom
claude/upgrade-ape-c-library-mmZGd
Nov 5, 2026
Merged

staalmannen merged 1 commit into
mainfrom
claude/upgrade-ape-c-library-mmZGd

Conversation

@staalmannen

Copy link
Copy Markdown
Owner

The ctime_r added in the previous commit broke the libap build, and the break was not in ctime_r:

ctime.c:80 incompatible types: "IND CHAR" and "INT" for op "RETURN"
warning: ctime.c:200 redeclaration of: asctime_r

Line 80 is return asctime_r(&tm, buf);'. asctime_r was declared by no APE header at all -- defined at ctime.c:200, 120 lines further down its own file, invisible to every caller including the one in the same translation unit -- so it was an implicit int' return and the char * came back truncated. This tree's oldest invariant, in a POSIX function that has been in libap all along.

The warning beside the error says the opposite of what it looks like: `redeclaration of: asctime_r' at the DEFINITION is kencc objecting to the implicit declaration it had just created at line 80, not to anything in a header. Read that way it is a second statement of the same fact rather than a separate complaint.

<time.h> declares it now. The external/ grep before adding the name found 56 files mentioning it and every one is gnulib's `#undef asctime_r' / _GL_WARN_ON_USE pair, which a plain extern does not disturb; nothing declares it as anything else.

And apdecl-sweep.py ran clean over it, which is not a fault in the sweep but its sharpest limit made concrete: it compares a call against a DECLARED return type, so a function no header has ever heard of has nothing to compare against and reads as an ordinary int call. Its header says so now. The inverse question -- what does libap define that no header declares -- has no instrument yet.

Claude-Session: https://claude.ai/code/session_01WGAwvvTwDg2yknFkmZ3qzs

The ctime_r added in the previous commit broke the libap build, and
the break was not in ctime_r:

	ctime.c:80 incompatible types: "IND CHAR" and "INT" for op "RETURN"
	warning: ctime.c:200 redeclaration of: asctime_r

Line 80 is `return asctime_r(&tm, buf);'.  asctime_r was declared by
no APE header at all -- defined at ctime.c:200, 120 lines further down
its own file, invisible to every caller including the one in the same
translation unit -- so it was an implicit `int' return and the char *
came back truncated.  This tree's oldest invariant, in a POSIX
function that has been in libap all along.

The warning beside the error says the opposite of what it looks like:
`redeclaration of: asctime_r' at the DEFINITION is kencc objecting to
the implicit declaration it had just created at line 80, not to
anything in a header.  Read that way it is a second statement of the
same fact rather than a separate complaint.

<time.h> declares it now.  The external/ grep before adding the name
found 56 files mentioning it and every one is gnulib's
`#undef asctime_r' / _GL_WARN_ON_USE pair, which a plain extern does
not disturb; nothing declares it as anything else.

And apdecl-sweep.py ran clean over it, which is not a fault in the
sweep but its sharpest limit made concrete: it compares a call against
a DECLARED return type, so a function no header has ever heard of has
nothing to compare against and reads as an ordinary int call.  Its
header says so now.  The inverse question -- what does libap define
that no header declares -- has no instrument yet.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WGAwvvTwDg2yknFkmZ3qzs
@staalmannen
staalmannen merged commit 8acdf7b into main Nov 5, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants