小编thi*_*his的帖子

严格的别名和内存位置

严格别名会阻止我们使用不兼容的类型访问相同的内存位置.

int* i = malloc( sizeof( int ) ) ;  //assuming sizeof( int ) >= sizeof( float )
*i = 123 ;
float* f = ( float* )i ;
*f = 3.14f ;
Run Code Online (Sandbox Code Playgroud)

根据C标准,这将是非法的,因为编译器"知道" 左值int不能访问float.

如果我使用该指针指向正确的内存,如下所示:

int* i = malloc( sizeof( int ) + sizeof( float ) + MAX_PAD ) ;
*i = 456 ;
Run Code Online (Sandbox Code Playgroud)

首先,我为内存分配内存int,float最后一部分是允许float存储在对齐地址的内存.float需要在4的倍数上对齐,MAX_PAD通常是16个字节中的8个,具体取决于系统.在任何情况下,MAX_PAD足够大,所以float可以正确对齐.

然后,我写的int进入i,到目前为止,一切顺利.

float* …
Run Code Online (Sandbox Code Playgroud)

c memory standards strict-aliasing

15
推荐指数
2
解决办法
1985
查看次数

这是main()的有效定义吗?

C11标准声明:

5.1.2.2.1程序启动

  1. 程序启动时调用的函数名为main.该实现声明此函数没有原型.它应定义为返回类型int且没有参数:

    int main(void) { /* ... */ }
    
    Run Code Online (Sandbox Code Playgroud)

    或者有两个参数(这里称为argcargv,虽然可以使用任何名称,因为它们是声明它们的函数的本地名称):

    int main(int argc, char *argv[]) { /* ... */ }
    
    Run Code Online (Sandbox Code Playgroud)

    或同等学历; 10),或以某种其他实现定义的方式.


10)因此,int可以被typedef定义为的名称替换int,或者argv可以写成类型char ** argv,等等.

我们将忽略这一部分:或者以其他一些实现定义的方式.因为我只对与上述两个例子相当的定义感兴趣.

这是否是main的有效定义,char* a[4]并且char**是等效的:

int main(int argc, char* argv[4]){/*...*/}
Run Code Online (Sandbox Code Playgroud)

我们假设一个VLA数组如何printf返回一个正的int值:

int main(int argc, char* argv[printf("Hello there!")]){/*...*/}
Run Code Online (Sandbox Code Playgroud)

c standards language-lawyer c11

8
推荐指数
1
解决办法
196
查看次数

将指针转换为指向数组的指针

以下是代码段.我想知道line no. 17在c中类型转换是否合法?

#include <stdio.h>

typedef int twoInts[2];

void print(twoInts *twoIntsPtr);
void intermediate (twoInts twoIntsAppearsByValue);

int main () {
    twoInts a;
    a[0] = 0;
    a[1] = 1;
    print(&a);
    intermediate(a);
    return 0;
}
void intermediate(twoInts b) {
    print((int(*)[])b); // <<< line no. 17 <<<
}

void print(twoInts *c){
    printf("%d\n%d\n", (*c)[0], (*c)[1]);
}
Run Code Online (Sandbox Code Playgroud)

此外,当我将定义更改intermediate

void intermediate(twoInts b) {
    print(&b);
}
Run Code Online (Sandbox Code Playgroud)

我在编译时遇到警告,而o/p不正确.

1.c:17:11: warning: passing argument 1 of print from incompatible pointer type
     print(&b);
           ^
1.c:5:6: note: expected int …
Run Code Online (Sandbox Code Playgroud)

c

5
推荐指数
1
解决办法
856
查看次数

Memcpy实现,严格别名

在学习c的同时,我实现了自己的memcpy功能.我uint32_t在函数中使用了更宽的类型().(为简单起见,该函数仅限于4的倍数且数据正确对齐的类型)

void memcpy4( void* dst , void* src , int size )
{
    size /= 4;

    for ( int i = 0 ; i < size ; i++ )
        ((uint32_t*)dst)[i] = ((uint32_t*)src)[i];
}
Run Code Online (Sandbox Code Playgroud)

我做了关于类型惩罚和严格别名的阅读,我相信上面的功能打破了规则.正确的实现是这样的,因为你可以使用char:

void memcpy4( void* dst , void* src , int size )
{
    for ( int i = 0 ; i < size ; i++ )
        ((char *)dst)[i] = ((char *)src)[i];
}
Run Code Online (Sandbox Code Playgroud)

我试图通过一个联盟进行一些投射,但事实证明这也是无效的.

如何用更广泛的类型实现这样的功能而不破坏严格的别名规则?

c c++ strict-aliasing memcpy

3
推荐指数
1
解决办法
1120
查看次数

转换struct指针

假设使用c11编译代码并启用严格别名.

我不是在寻找一种不同的方法,我想关注这个具体的问题,如果它有效或者为什么不能.

(如果我无意中犯了一些无关的错误,请告诉我,我会修复它)

c11标准说:

6.2.5.28所有指向结构类型的指针应具有相同的表示和对齐要求.

6.7.2.1.6结构是由一系列成员组成的类型,其存储按有序顺序分配

这意味着结构A和B中指针大小和指针对齐方式相同.

#include <stdio.h>
#include <stdlib.h>

struct S1
{
    int i ;
} ;

struct S2
{
    float f ;
} ;

struct A
{
    struct S1* p ;
} ;


struct B
{
    struct S2* p ;
} ;


int main( void )
{
Run Code Online (Sandbox Code Playgroud)

结构A和B具有指向结构S1和S2的指针,结构A和B保证具有相同的大小和对齐.

我们有一个struct B成员指针是struct S2指针,但指向一些struct S1,它使用void*cast实现.

struct S1 s1 = { 0 } ;

struct B* b = malloc( sizeof( *b ) ) ;
b->p = ( void* ) …
Run Code Online (Sandbox Code Playgroud)

c struct pointers c11

3
推荐指数
1
解决办法
4563
查看次数

C90中的可变长度结构

GNU C中允许零长度数组,因此可以进行初始化

struct line {
       int length;
       char contents[0];
     };

     struct line *thisline = (struct line *)
       malloc (sizeof (struct line) + this_length);
     thisline->length = this_length;
Run Code Online (Sandbox Code Playgroud)

注意:我在这里指的是这个页面:http://gcc.gnu.org/onlinedocs/gcc/Zero-Length.html (提供C中可变长度结构的基本介绍)

它继续说:"在ISO C90中,你必须给内容一个长度为1,这意味着你要浪费空间或使参数复杂化为malloc."

那是什么意思?有人可以举例说明如何在C90中初始化变长结构以帮助理解吗?

c gcc c89

3
推荐指数
1
解决办法
568
查看次数

对CLSID_MMDeviceEnumerator和IID_IMMDeviceEnumerator的未定义引用

尝试使用COM和CoCreateInstance()在C中使用MinGW-w64编译示例代码失败.

#include <windows.h>
#include <mmdeviceapi.h>
#include <endpointvolume.h>

#include <stdlib.h>
#include <stdio.h>

extern const CLSID CLSID_MMDeviceEnumerator;
extern const IID IID_IMMDeviceEnumerator;

int main( void )
{
    CoInitialize( NULL );

    LPVOID device = NULL;
    const HRESULT ok = CoCreateInstance(    &CLSID_MMDeviceEnumerator, NULL, 
                                            CLSCTX_INPROC_SERVER, &IID_IMMDeviceEnumerator, 
                                            &device );  
    CoUninitialize();

return EXIT_SUCCESS;
}
Run Code Online (Sandbox Code Playgroud)

编译:gcc main.c libole32.a -Wall -Wextra -oa

即使在mmdeviceapi.h中定义了CLSID_MMDeviceEnumerator,也找不到它.实际上从示例代码中删除我的extern定义给出了相同的结果,因为两个externs似乎都在mmdeviceapi.h中定义

当我使用__uuidof并使用g ++进行编译时,代码工作正常,但__uuidof的这个C"替换"却没有.

为什么没有找到COM标识符?

c com winapi windows-7 mingw-w64

3
推荐指数
1
解决办法
1300
查看次数

浮点返回值,表示错误

我的函数从对象返回一个浮点值.如果函数找不到合适的浮点值,则应返回错误,以便我可以在代码中正确处理它.

我的问题是如何返回错误.

添加额外参数并使用它来设置错误标记的选项不是首选.

我可以返回一个神奇的值,这是一个有效的选项吗?我在程序中的浮点值永远不会超过非常大的数字(从不超过10 ^ 12),因此返回FLT_MAX来检查错误可能是一个选项.

有更好的(便携式)方式吗?

c

2
推荐指数
2
解决办法
1015
查看次数

取消引用指向结构的指针以访问其第一个成员

出于特定原因,我想通过取消引用结构的指针来仅访问结构的第一个成员.

我想知道这是否合法,或者在某些情况下是否会导致UB; 什么是正确的解决方案,如果这个有任何问题.

谢谢.

#include <stdio.h>
#include <stdlib.h>

typedef struct test_s
{
    void * data ;
    struct test_s * next ;

} test_t ;


int main( void )
{
    test_t * t = calloc( 1 , sizeof( test_t ) ) ;

    int n = 123;

    t->data = &n ; //int is used only for an address, this could be anything, an object for example
    void ** v = ( void* )t ;
    printf("Address of  n: %p\nAddress of *t: %p\n\n" , …
Run Code Online (Sandbox Code Playgroud)

c struct pointers dereference

2
推荐指数
1
解决办法
7076
查看次数

使用const成员将结构转换为结构

我有一个结构定义,只在声明它的.c文件中可见.

struct private
{
    int n ;
    void* data ;

    int field ;
}
Run Code Online (Sandbox Code Playgroud)

访问成员的唯一方法是在同一文件中定义并在标头中声明的函数.

我声明了一个在任何地方都可见的标题中的结构

struct public
{
    int n ;
    void* data ;
}
Run Code Online (Sandbox Code Playgroud)

然后我有一个函数返回实际上私有结构化的公共结构

struct public* this = GetPrivateStruct() ;    //function returns pointer to struct private malloced internally, casted to public struct 
this->n = 123 ;
Run Code Online (Sandbox Code Playgroud)

到目前为止,代码是正确的,没有未定义的行为.

但是,我可以使用const成员来创建公共结构吗?

struct public
{
    const int n ;
    const void* data ;
}
Run Code Online (Sandbox Code Playgroud)

所以只允许阅读:

void* private_struct = GetPrivateStruct() ;
struct public* this = ( struct public* )private_struct ;
this->n = …
Run Code Online (Sandbox Code Playgroud)

c struct pointers const c99

1
推荐指数
1
解决办法
1462
查看次数

LPCSTR没有'long'而UINT_PTR没有指针?

在此网站上:Windows数据类型

出现了这个话题的问题.

LP代表我认为的长指针 - 但不久.UINT_PTR代表无符号的int指针我再次设定 - 但是没有指针.

有人知道这个背景吗?

c c++ msdn pointers

1
推荐指数
2
解决办法
119
查看次数

在C中使用`this`关键字是明智的吗?

基本上,我在C中有一个内联函数:

struct array {
    unsigned long size;
    void* items;
};
typedef struct array* Array;
inline Array array_create(unsigned long initsize);
inline void  array_free(Array this);
Run Code Online (Sandbox Code Playgroud)

我是否可以this在这种情况下自由使用关键字,或者更好地避免它,以及为什么(不是)?

编辑:这个问题起源于我使用的代码中的一个错误,inline void array_free(Array array);它改变了结果sizeof(array);并给了我使用的想法,this而不是适应(在我看来丑陋)sizeof(struct array);.

c class c99 this

0
推荐指数
3
解决办法
2699
查看次数

c#检查日期时间是否有效

我在C#中创建自己的DateTime类,由于某种原因我的检查不起作用.当我运行程序并输入一个日期时,它总是停止并到达"Day"方法的最后一行并说"ArgumentOutOfException.无论如何要解决这个问题并使我的检查称为"值"工作?

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace date
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("\t\t\t\t\t\tNextDate Application\n\t\t\t\t\t-------------------------------------");

            Console.WriteLine("please enter date as dd/MM/yyyy");
            int day;
            int month;
            int year;

            string[] read = Console.ReadLine().Split('/');
            day = int.Parse(read[0]);
            month = int.Parse(read[1]);
            year = int.Parse(read[2]);

            Date date = new Date(day, month, year);
            Console.WriteLine("{0}/{1}/{2}", date.Day, date.Month, date.Year);
            Console.ReadLine();
        }

        class Date
        {
            private int _month; // 1-12
            private int _day; // 1-31 depending on month
            private int _year; …
Run Code Online (Sandbox Code Playgroud)

.net c# datetime visual-studio

-6
推荐指数
2
解决办法
532
查看次数