summaryrefslogtreecommitdiffstats
path: root/compiler/rustc_error_codes/src/error_codes/E0060.md
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/rustc_error_codes/src/error_codes/E0060.md')
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0060.md38
1 files changed, 38 insertions, 0 deletions
diff --git a/compiler/rustc_error_codes/src/error_codes/E0060.md b/compiler/rustc_error_codes/src/error_codes/E0060.md
new file mode 100644
index 000000000..54b10c886
--- /dev/null
+++ b/compiler/rustc_error_codes/src/error_codes/E0060.md
@@ -0,0 +1,38 @@
+External C functions are allowed to be variadic. However, a variadic function
+takes a minimum number of arguments. For example, consider C's variadic `printf`
+function:
+
+```compile_fail,E0060
+use std::os::raw::{c_char, c_int};
+
+extern "C" {
+ fn printf(_: *const c_char, ...) -> c_int;
+}
+
+unsafe { printf(); } // error!
+```
+
+Using this declaration, it must be called with at least one argument, so
+simply calling `printf()` is invalid. But the following uses are allowed:
+
+```
+# use std::os::raw::{c_char, c_int};
+# #[cfg_attr(all(windows, target_env = "msvc"),
+# link(name = "legacy_stdio_definitions",
+# kind = "static", modifiers = "-bundle"))]
+# extern "C" { fn printf(_: *const c_char, ...) -> c_int; }
+# fn main() {
+unsafe {
+ use std::ffi::CString;
+
+ let fmt = CString::new("test\n").unwrap();
+ printf(fmt.as_ptr());
+
+ let fmt = CString::new("number = %d\n").unwrap();
+ printf(fmt.as_ptr(), 3);
+
+ let fmt = CString::new("%d, %d\n").unwrap();
+ printf(fmt.as_ptr(), 10, 5);
+}
+# }
+```