You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
build this function to a static lib _initd.lib, link it by cmake: "set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -L${CMAKE_CURRENT_LIST_DIR}/libs -l_initd.lib ")"
howevery, "?" not printed, and __builtin_cpu_supports always return false in main.cpp
Isn't that always the behavior of static libraries? If an object file in a .a isn't needed to complete the link, then it's discarded, even if it has constructors. This allows garbage collecting unused constructors, and allowing some forms of fallback implementations, where a function is taken from the main program if it exists, but a fallback is taken from a .a if needed. (I believe that's how DllMain works.)
I agree it's unexpected and occasionally unhelpful, though. It would be useful to have a 'always include this object from the .a, even if seemingly unnecessary' switch somewhere.
int main(int, char **){
//lldtest();
__builtin_cpu_supports("avx"); // false
}
if lldtest() called, then _init_cpu_features will run before main(), else, _init_cpu_features dont work.
does the linker discard the entire static library if no symboles ars explicitly referenced in it?
Isn't that always the behavior of static libraries? If an object file in a .a isn't needed to complete the link, then it's discarded, even if it has constructors. This allows garbage collecting unused constructors, and allowing some forms of fallback implementations, where a function is taken from the main program if it exists, but a fallback is taken from a .a if needed. (I believe that's how DllMain works.)
I agree it's unexpected and occasionally unhelpful, though. It would be useful to have a 'always include this object from the .a, even if seemingly unnecessary' switch somewhere.
Thanks, i roughly understand now, the linker tries to discard seemingly unused code.
But according to my latest test: when other symbols unrelated to this constructor are explicitly called in the .a file, the constructor is not discarded and executes normally. perhaps this involves more than just garbage collection logic?
Activity
Eternalni commentedon Jun 18, 2025
call _init_cpu_features(); in function main, will print two "?". if never called it, no print
Alcaro commentedon Jun 18, 2025
Isn't that always the behavior of static libraries? If an object file in a .a isn't needed to complete the link, then it's discarded, even if it has constructors. This allows garbage collecting unused constructors, and allowing some forms of fallback implementations, where a function is taken from the main program if it exists, but a fallback is taken from a .a if needed. (I believe that's how DllMain works.)
I agree it's unexpected and occasionally unhelpful, though. It would be useful to have a 'always include this object from the .a, even if seemingly unnecessary' switch somewhere.
Eternalni commentedon Jun 18, 2025
init.lib:
[[gnu::used, gnu::retain, gnu::constructor(101)]]
void _init_cpu_features(){
__builtin_cpu_init();
std::cout << "init" << std::endl;
}
void lldtest() { std::cout << "test" << std::endl; }
main.cpp:
int main(int, char **){
//lldtest();
__builtin_cpu_supports("avx"); // false
}
if lldtest() called, then _init_cpu_features will run before main(), else, _init_cpu_features dont work.
does the linker discard the entire static library if no symboles ars explicitly referenced in it?
Eternalni commentedon Jun 18, 2025
Thanks, i roughly understand now, the linker tries to discard seemingly unused code.
But according to my latest test: when other symbols unrelated to this constructor are explicitly called in the .a file, the constructor is not discarded and executes normally. perhaps this involves more than just garbage collection logic?