te')); return $arr; } /* 遍历用户所有主题 * @param $uid 用户ID * @param int $page 页数 * @param int $pagesize 每页记录条数 * @param bool $desc 排序方式 TRUE降序 FALSE升序 * @param string $key 返回的数组用那一列的值作为 key * @param array $col 查询哪些列 */ function thread_tid_find_by_uid($uid, $page = 1, $pagesize = 1000, $desc = TRUE, $key = 'tid', $col = array()) { if (empty($uid)) return array(); $orderby = TRUE == $desc ? -1 : 1; $arr = thread_tid__find($cond = array('uid' => $uid), array('tid' => $orderby), $page, $pagesize, $key, $col); return $arr; } // 遍历栏目下tid 支持数组 $fid = array(1,2,3) function thread_tid_find_by_fid($fid, $page = 1, $pagesize = 1000, $desc = TRUE) { if (empty($fid)) return array(); $orderby = TRUE == $desc ? -1 : 1; $arr = thread_tid__find($cond = array('fid' => $fid), array('tid' => $orderby), $page, $pagesize, 'tid', array('tid', 'verify_date')); return $arr; } function thread_tid_delete($tid) { if (empty($tid)) return FALSE; $r = thread_tid__delete(array('tid' => $tid)); return $r; } function thread_tid_count() { $n = thread_tid__count(); return $n; } // 统计用户主题数 大数量下严谨使用非主键统计 function thread_uid_count($uid) { $n = thread_tid__count(array('uid' => $uid)); return $n; } // 统计栏目主题数 大数量下严谨使用非主键统计 function thread_fid_count($fid) { $n = thread_tid__count(array('fid' => $fid)); return $n; } ?>c - Char Arrays as Compile-Time Constants - Stack Overflow
最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

c - Char Arrays as Compile-Time Constants - Stack Overflow

programmeradmin3浏览0评论

If we have a const char pointer initialized by a string literal, such as const char *str = "Hi!", then we cannot use str as a compile-time constant. This makes sense, str is a variable after all. But addresses are compile time constants, so we could use &str just fine.

The following workaround compiles with GCC and clang, with -Wall, -Wextra, -Wpedantic, -Weverything (clang only), and -std=c89).

#include <stdio.h>

/* Bad:
 *    static const char *str = "Hi!";
 */
static const char str[4] = {'H', 'i', '!', '\0'};
static struct {
    double x;
    const char *string;
} my_struct = {1.0, str};

int main(void)
{
    puts(my_struct.string);
    return 0;
}

After some searching, I was unable to find something in the C standard that would verify that this is legal and portable. My guess is that static const char str[4] is an array, so using str in the structs initialization is the same thing as using an address, which is a compile time constant, whereas using static const char *str is a pointer to an array, so using it amounts to using a variable, which is not a compile time constant.

Any references to the relevant sections in the standard are greatly appreciated.

If we have a const char pointer initialized by a string literal, such as const char *str = "Hi!", then we cannot use str as a compile-time constant. This makes sense, str is a variable after all. But addresses are compile time constants, so we could use &str just fine.

The following workaround compiles with GCC and clang, with -Wall, -Wextra, -Wpedantic, -Weverything (clang only), and -std=c89).

#include <stdio.h>

/* Bad:
 *    static const char *str = "Hi!";
 */
static const char str[4] = {'H', 'i', '!', '\0'};
static struct {
    double x;
    const char *string;
} my_struct = {1.0, str};

int main(void)
{
    puts(my_struct.string);
    return 0;
}

After some searching, I was unable to find something in the C standard that would verify that this is legal and portable. My guess is that static const char str[4] is an array, so using str in the structs initialization is the same thing as using an address, which is a compile time constant, whereas using static const char *str is a pointer to an array, so using it amounts to using a variable, which is not a compile time constant.

Any references to the relevant sections in the standard are greatly appreciated.

Share Improve this question asked Feb 17 at 15:49 Ryan MaguireRyan Maguire 1078 bronze badges 4
  • 2 BTW: You could also write static const char str[] = "Hi!"; to define and initialize an array of the correct size for the string literal. – Bodo Commented Feb 17 at 17:13
  • Note that the identifier str is potentially reserved by the implementation for any use. – Ian Abbott Commented Feb 17 at 17:18
  • 1 You could also initialize my_struct.string with an actual string literal "Hi!": static struct { … } my_struct = {1.0, "Hi!"};. – Ian Abbott Commented Feb 17 at 17:29
  • Thanks, Ian. Initializing via {1.0, "Hi!"}; is certainly the most elegant, but in the scenario I find myself in the string already exists as a static variable at the file scope. One could use a macro, but I suppose the hope here is to avoid repeated definitions of the same string. – Ryan Maguire Commented Feb 17 at 19:08
Add a comment  | 

1 Answer 1

Reset to default 4

You seem to be asking whether str, having been defined as a static const char str[4], can be used to initialize a member of a static structure.

C 2024 6.6 specifies constant expressions and includes:

More latitude is permitted for constant expressions in initializers. Such a constant expression shall be, or evaluate to, one of the following:

— an address constant, or…

and:

An address constant is a null pointer, a pointer to an lvalue designating an object of static storage duration,…

str is an array, not a pointer. However, in this use, it is automatically converted to a pointer to its first element. That first element is an object of static storage duration, and hence str evaluates to a pointer to an object of static storage duration, so it may be used as an initializer.

发布评论

评论列表(0)

  1. 暂无评论